我正在学习角度指令中的继承/隔离范围,并使用一些基本概念。请看下面的弹药。
场景1:
我有2个指令(书和细节)。我正在显示两个“Book Details”容器,并通过发送这样的自定义属性来切换书名。
<book bookdetails="book" collapsed="yes" list="list"></book>
<book bookdetails="book1" collapsed="no" list="list"></book>
问题:这是处理在两个不同容器中显示内容的正确方法吗?
情景2:
我想在容器1中隐藏作者详细信息部分,但在加载时显示在container2中。怎么做到这一点?
当我在下面使用这一行时,它会隐藏并显示作者详细信息部分,但我想将它保持分开。
<details collapsed="yes"></details>
我知道我缺乏使用继承/隔离范围的基本技能。有人可以教育我吗?
答案 0 :(得分:0)
可以使用像您一样使用的嵌套指令,这样您就可以执行与详细信息控制器中的详细信息窗格相关的所有操作,例如从书籍列表中删除项目。
如果你不在细节控制器中做任何逻辑,只是包含一些html,我会使用ng-include
。
我在改进代码时检测到的一些问题:
模板标记是部分html文件,因此无需添加标题,正文等。只需在指令中添加所需的标记。
我创建了一个模型数组books
,您可以使用ng-repeat
而不是两个单独的范围变量进行迭代。这样可以更轻松地添加更多图书。
我不会将折叠状态传递给指令隔离范围。我会将它添加到书籍模型中,然后您可以拥有详细窗格的独立状态。
您还可以创建与模型分开的折叠数组范围变量,如果您不想将其添加到模型中,请使用ng-hide='collapsed[$index]'
。
不要与字符串yes
进行比较。它使事情变得更加复杂。最好使用true
或false
。
如果您想为每个详细信息窗格使用一个列表,那么您传递的列表就可以了。但我认为你需要彼此独立,所以将它添加到你的书模型中。
对于toggeling值,您可以使用js简写:collapsed = !collapsed;
。它采用折叠的值并将其反转并重新将其折叠。
详细信息指令:您不需要将属性传递给不使用隔离范围的指令。相反,您可以直接使用父级的继承范围。
注意:我认为您应该查看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);
}
}
}
})
&#13;
<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}}
<button class="btn btn-danger" ng-click="removeItem($index)">X</button>
</p>
</div>
</li>
<!--</ul>
</li>-->
</ul>
</div>
</div>
</script>
</div>
&#13;