我有以下标记:
<div class="controller" ng-controller="mainController">
<input type="text" ng-model="value">
<div class="matches"
positions="{{client.positions | filter:value}}"
select="selectPosition(pos)">
<div class="match"
ng-repeat="match in matches"
ng-click="select({pos: match})"
ng-bind="match.name">
然后,在我的matches
指令中我有
app.directive('matches', function()
{
return {
scope: {
select: '&'
},
link: function(scope, element, attrs)
{
scope.matches = [];
attrs.$observe('positions', function(value)
{
scope.matches = angular.fromJson(value);
scope.$apply();
})
}
}
}
当我这样做时,我可以控制log scope.matches
,它确实随着我输入的值而改变。然而,最后一个div .match
不渲染任何东西!如果我删除scope: {...}
并将其替换为scope: true
,那么它确实呈现结果,但我想使用&
评估来执行主控制器内的函数。
我该怎么办?
使用scope.$watch
代替,您可以监视属性select
,无论何时对该属性进行更改。
app.directive('matches', function()
{
return {
scope: true,
link: function(scope, element, attrs)
{
scope.matches = [];
scope.$watch(attrs.select, function(value) {
scope.matches = angular.fromJson(value);
});
}
}
}
UPDATE:同样地,如果你将select
本身定义为作用域属性,你必须使用=
表示法(如果你打算将其用作指令中定义的模板中的回调,则只能使用&
表示法),并且使用scope.$watch()
,而不是attr.$observe()
。由于attr.$observe()
只用于插值更改{{}}
,而$watch用于scope属性本身的更改。
app.directive('matches', function()
{
return {
scope: {select: '='},
link: function(scope, element, attrs)
{
scope.matches = [];
scope.$watch('select', function(value) {
scope.matches = angular.fromJson(value);
});
}
}
}
AngularJS文档说明:
观察美元(关键,fn);
观察到一个插入的属性。
观察者函数将在下一个$digest中调用一次后编译。对象时调用观察者插值值变化
在指令定义中定义scope
的问题中没有定义这样的范围属性。
如果不需要隔离作用域,可以使用$parse
代替&
,如下所示:
var selectFn = $parse(attrs.select);
scope.select = function (obj) {
selectFn(scope, obj);
};
示例Plunker: http://plnkr.co/edit/QZy6TQChAw5fEXYtw8wt?p=preview
但是如果你喜欢孤立的作用域,你必须跨出子元素,并正确地分配指令的作用域,像这样:
app.directive('matches', function($parse) {
return {
restrict: 'C',
scope: {
select: '&',
},
transclude: true,
link: function(scope, element, attrs, ctrl, transcludeFn) {
transcludeFn(scope, function (clone) {
element.append(clone);
});
scope.matches = [];
attrs.$observe('positions', function(value) {
scope.matches = angular.fromJson(value);
});
}
}
});
示例Plunker: http://plnkr.co/edit/9SPhTG08uUd440nBxGju?p=preview