无法在我的示例plunker中使用继承/隔离的范围概念

Unable to use inherited/isolated scope concept in my example plunker

本文关键字:隔离 继承 范围 我的 plunker      更新时间:2023-09-26

我正在学习角度指令中的继承/隔离范围,并掌握了一些基本概念。请看下面的撞球。

示例。

场景1:

我有两个指令(书籍和细节)。我显示了两个"图书详细信息"容器,并通过发送这样的自定义属性来切换图书名称。

 <book bookdetails="book" collapsed="yes" list="list"></book> 
 <book bookdetails="book1" collapsed="no" list="list"></book>    

问题:这是处理在两个不同容器中显示事物的正确方法吗?

场景2:

我想在容器1中隐藏作者详细信息部分,但在加载时显示在容器2中。如何做到这一点?

当我使用下面的这一行时,它将隐藏并显示两个作者详细信息部分,但我想将其分开。

<details collapsed="yes"></details> 

我知道我缺乏使用继承/孤立范围的基本技能。有人能教育我吗?

可以像您使用的那样使用嵌套指令,这样您就可以在详细信息控制器中执行与详细信息窗格相关的所有操作,比如从图书列表中删除项目。

如果你不想在细节控制器中做任何逻辑,只包含一些html,我只会使用ng-include

我在改进你的代码时发现了一些问题:

  • 模板标记是部分html文件,因此不需要添加标题、正文等。只需在指令中添加所需的标记即可。

  • 我创建了一个模型数组books,您可以使用ng-repeat而不是两个单独的作用域变量对其进行迭代。添加更多的书会更容易。

  • 我不会将崩溃状态传递给指令隔离范围。我会将它添加到图书模型中,然后您就可以拥有独立的详细信息窗格状态。如果您不想将其添加到模型中,也可以创建一个独立于模型的折叠数组范围变量,并像ng-hide='collapsed[$index]'一样使用它。

  • 不要与字符串yes进行比较。这让事情变得更加复杂。最好使用truefalse

  • 如果您希望为每个详细信息窗格使用一个列表,那么您传递的列表是可以的。但我认为你需要它们彼此独立,所以把它添加到你的书模型中。

  • 对于切换值,可以使用js简写:collapsed = !collapsed;。它获取collapsed的值,并将其反转,然后重新设定为collapsed。

  • Details指令:不需要将属性传递给不使用隔离作用域的指令。相反,您可以直接使用父级的继承作用域。

注意:我认为您应该看看angular-ui-bootstrap,稍后使用手风琴而不是手动创建的窗格。但对于学习指令,你的代码是可以的。

请在下面或这个plunker中查看您的更新代码。

如果有什么不清楚的地方,请随时添加评论,我会尽力提供帮助。

angular.module('plunker', [])
  .controller('MainCtrl', function($scope) {
    $scope.books = [{
      id: 0,
      name: 'Building modern ASP.NET 5',
      author: {
        name: 'name1',
        age: 31,
        country: 'USA'
      },
      collapsed: false,
      list: [{
        id: 0,
        name: 'book1'
      }, {
        id: 1,
        name: 'book2'
      }, {
        id: 2,
        name: 'book3'
      }]
    }, {
      id: 1,
      name: 'AngularJS',
      author: {
        name: 'name2',
        age: 27,
        country: 'USA'
      },
      collapsed: true,
      list: [{
        id: 0,
        name: 'book1'
      }, {
        id: 1,
        name: 'book2'
      }, {
        id: 2,
        name: 'book3'
      }]
    }];
    //$scope.list =  ["book1", "book2", "book3"];
  }).directive('book', function() {
    return {
      restrict: 'E',
      templateUrl: 'book.html',
      scope: {
        bkdet: "=bookdetails"
          //list: "="
          //collapsed: "@"
      },
      controller: function($scope) {
        $scope.toggleDetails = function() {
          $scope.bkdet.collapsed = !$scope.bkdet.collapsed;
          updateCaption();
        };
        function updateCaption() {
          $scope.hypshowhide = $scope.bkdet.collapsed ? 'show details' : 'hide details';
        }
        // first run
        updateCaption();
        /*if ($scope.collapsed == 'yes')
        {
            $scope.dethide = true;
        }
        else {
            $scope.dethide = false;
        }        */
        //$scope.hypshowhide = 'show details';
      }
    }
  })
  .directive('details', function() {
    return {
      restrict: 'E',
      templateUrl: 'details.html',
      controller: function($scope) {
        /*console.log($scope.bkdet.collapsed);
        if (!$scope.bkdet.collapsed) { //== 'yes') {
            $scope.dethide = true;
        }
        else {
            $scope.dethide = false;
        }*/
        $scope.removeItem = function(index) {
          $scope.bkdet.list.splice(index, 1);
        }
      }
    }
  })
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="plunker">
  <div ng-controller="MainCtrl">
    <div class="container">
      <book bookdetails="book" ng-repeat="book in books"></book>
    </div>
  </div>
  <script type="text/ng-template" id="book.html">
    <div class="row">
      <div class="panel panel-default">
        <div class="panel-heading">
          <h1>Book Details</h1>
        </div>
        <div class="panel-body">
          <a class="pull-right" href="#" ng-click="toggleDetails(collapsed)">{{hypshowhide}}</a>
          <div>
            <!--ng-hide="dethide">-->
            {{bkdet.name}}
          </div>
          <!--<details collapsed="no"></details>-->
          <details></details>
        </div>
      </div>
    </div>
  </script>
  <script type="text/ng-template" id="details.html">
    <div class="container" ng-hide="bkdet.collapsed">
      <div class="row">
        <ul class="list-group list-unstyled">
          <!--<li>
            <h1>Author:</h1>
        </li>
        <li>
            <ul>-->
          <li>
            <strong>Author</strong>
            {{bkdet.author.name}}
          </li>
          <li>
            <strong>Age</strong>
            {{bkdet.author.age}}
          </li>
          <li>
            <strong>Country</strong>
            {{bkdet.author.country}}
          </li>
          <li>
            <div ng-if="bkdet.list.length == 0">
              <p>No books here!</p>
            </div>
            <div ng-repeat="c in bkdet.list">
              <p>
                {{c.name}}&nbsp;
                <button class="btn btn-danger" ng-click="removeItem($index)">X</button>
              </p>
            </div>
          </li>
          <!--</ul>
        </li>-->
        </ul>
      </div>
    </div>
  </script>
</div>