当我将控制器中但与DOM相关的代码移动到指令时,我遇到了ng类初始化问题。简而言之,这里有一些代码:
view.html
<div ng-repeat="foo in foos" ng-click="rowClick($index)>
<div ng-class="changeOpacity($index)>
<span>{{foo.title}}</span>
<span>{{foo.name}}</span>
<span>{{foo.date}}</span>
...
// some div with hidden content. Show when clicking on the div
</div>
<div>
controller.js
$scope.rowClick = function (idx) {
// unfold the clicked div to show content
};
$scope.changeOpacity = function (idx) {
if (this is the div clicked) {
return {dark: true};
} else {
return {light: true};
}
所以当我有一个div列表时。当我点击一个div时,除了这个,所有其他的div都会变暗。
当$scope.rowClick和$scope.changeOpacity在我的控制器中时,一切都很好。
当我移动rowClick并将Opcaity更改为指令时:
myBar.js
myApp.directive('myBar', function () {
...
return {
restrict:'A',
link: function (scope, element) {
element.bind('click', function () {
...
same code from rowClick
...
scope.changeOpacity = function () {
...
same code from changeOpacity
}
scope.$apply();
}
}),
changeOpacity: function () {
...
return {light: true} // for all divs
}
}
});
现在我的view.html是这样的:
<div ng-repeat="foo in foos" ng-click="rowClick($index) my-bar>
<div ng-class="changeOpacity($index)>
<span>{{foo.title}}</span>
<span>{{foo.name}}</span>
<span>{{foo.date}}</span>
...
// some div with hidden content. Show when clicking on the div
</div>
<div>
但是现在div不再使用ng类进行初始化。我必须在每个div上单击一次来初始化它,并使用链接函数来监听单击。
如何初始化指令中的ng类?
Thanx。
问题是,只有在单击之后,才将changeOpacity
函数放入您的作用域中。在链接功能中这样做:
link: function (scope, element) {
scope.changeOpacity = function () {
...
same code from changeOpacity
}
}
使其成为"指令对象"的字段没有任何效果。
但是,在我看来,使用模型属性来指示元素是否处于活动状态并在ng-click
属性中更改此属性会更为优雅。然后可以在ng-class
指令中引用此属性。
类似这样的东西:
<div ng-repeat="foo in foos" ng-click="foo.active = true>
<div ng-class="{light: active, dark: !active }>
<span>{{foo.title}}</span>
<span>{{foo.name}}</span>
<span>{{foo.date}}</span>
<div ng-show="foo.active">
// some div with hidden content. Show when clicking on the div
</div>
</div>
ng-repeat
为数组中的每个项创建一个子作用域。这意味着ng-repeat
中指令的作用域将是子作用域。因此,您可以直接在该子作用域上设置属性,并使用ng-class
、ng-show
等
以下是基于ng-click
处理程序的切换状态指令的基本示例
HTML
<div ng-repeat="foo in foos" ng-click="rowClick($index)" my-directive parent-array="foos">
<div ng-class="{activeClass: foo.isActive}" class="item">
<span>{{foo.name}}</span>
<div ng-show="foo.isActive">Hidden content {{$index+1}}</div>
</div>
</div>
指令
app.directive('myDirective',function(){
return function(scope,elem,attrs){
/* ng-repeat adds properties like `$first` , `$last` that can be helpful*/
/* set default first element active*/
if(scope.$first){
scope.foo.isActive=true;
}
var parentArray=scope[attrs.parentArray];
/* update active state across array*/
scope.rowClick=function(idx){
angular.forEach(parentArray,function(item, index){
item.isActive = idx==index
})
}
}
})
演示
以下是另一种将currSelected
项存储在父作用域(控制器)中的方法
app.directive('myDirective',function(){
return function(scope,elem,attrs){
/* set default first element active*/
if(scope.$first){
scope.foo.isActive=true;
scope.$parent.currSelected=scope.foo
}
/* reset previous activeitem and make item clicked the active one*/
scope.rowClick=function(item){
scope.$parent.currSelected.isActive=false
scope.$parent.currSelected=item;
item.isActive=true
}
}
})
DEMO