我是AngularJS的新手。
有人可以解释为什么活动类不会在此代码中的标签之间切换:http://jsfiddle.net/eSe2y/1/?
angular.module('myApp', [])
.filter('split', function () {
return function (input, string) {
var temp = string.split('|');
for (var i in temp)
input.push(temp[i]);
return input;
};
})
.directive('myTabs', function () {
return {
restrict: 'E',
scope: { tabs: '@' },
template:
"<div>" +
"<a ng-repeat='e in [] | split:tabs' ng-click='selectedIndex = $index' ng-class='{active:$index==selectedIndex}'>{{e}}</a>" +
"</div>",
replace: true
}
});
如果我将ng-click表达式移动到控制器的方法,则代码按预期工作:http://jsfiddle.net/g36DY/1/。
angular.module('myApp', [])
.filter('split', function () {
return function (input, string) {
var temp = string.split('|');
for (var i in temp)
input.push(temp[i]);
return input;
};
})
.directive('myTabs', function () {
return {
restrict: 'E',
scope: { tabs: '@' },
template:
"<div>" +
"<a ng-repeat='e in [] | split:tabs' ng-click='onSelect($index)' ng-class='{active:$index==selectedIndex}'>{{e}}</a>" +
"</div>",
replace: true,
controller: ['$scope', function ($scope) {
$scope.onSelect = function (index) {
$scope.selectedIndex = index;
}
}]
}
});
有人可以解释我的区别吗?以及如何修改第一个代码以使其工作而无需为控制器创建方法?
提前致谢。
答案 0 :(得分:3)
问题解释
问题与javascript inheritance as it relates to scopes and directives in angular有关。基本上,当在子范围内时,从父级复制基本类型(int,boolean等)的所有属性。
在您的情况下,ng-repeat指令为每个元素创建子范围,因此每个链接都有自己的范围。在第一个示例中,selectedIndex
仅在转发器中引用,每个转发器元素引用其自己的selectedIndex
副本。您可以使用
在第二个示例中,您在控制器中定义了一个selectedIndex
对象,它是转发器的父作用域。因为selectedIndex
属性在传递到控制器时最初是未定义的,所以它们会向父级查找定义。当此定义在onSelect
方法中设置了值时,所有转发器元素都“看到”此值,并相应地更新。
如何调试
将来,您可以使用Angular Batarang调查这些类型问题。
在第二个小提琴上,尝试仅查看每个标签上的$scope
(不是$scope.selectedIndex
)。您将看到未在转发器元素上定义selectedIndex
,因此它们默认为其父级的值。
最佳做法
避免此问题的典型角度最佳做法是始终引用可能在“点后”范围内更改的项目。这利用了JavaScript对象通过引用继承的事实,因此当属性在一个位置更改时,它会更改父子层次结构中的所有范围。我发布了一个更新的提琴手,通过简单地将绑定推送到对象上来解决问题:
angular.module('myApp', [])
.filter('split', function () {
return function (input, string) {
var temp = string.split('|');
for (var i in temp)
input.push(temp[i]);
return input;
};
})
.directive('myTabs', function () {
return {
restrict: 'E',
scope: { tabs: '@' },
template:
"<div>" +
"<a ng-repeat='e in [] | split:tabs' ng-click='s.selectedIndex = $index' ng-class='{active:$index==s.selectedIndex}'>{{e}}</a>" +
"</div>",
replace: true,
controller: ['$scope', function ($scope) {
$scope.s = {};
}]
}
});