AngularJS : 为什么我的手表不响?
AngularJS : Why is my watch not firing?
我确信这将是其中的一件事 "duh",但我似乎无法弄清楚为什么我的手表在我的指令中会触发。
我有一个指令要写出一些关于有问题的项目。我试图通过
引用该项目
scope: {
item: '=criteriaDescription'
}
以及使用 $parse,所以我不必有一个独立的范围,两者似乎都不起作用,因为我的 'changed' 代码没有被调用。这是我的指令
angular.module('app').directive('criteriaDescription', ['$parse', function ($parse) {
'use strict';
return {
restrict: 'A',
link: function (scope, element, attrs) {
var item = $parse(attrs.criteriaDescription)(scope);
// generate a description for this criteria item, based on values and options
scope.$watch(function () {
return item;
}, function (newValue, oldValue) {
var desc = 'You have a name of ' + newValue.name;
element.html(desc);
});
}
};
}]);
我使用该指令的 HTML 看起来像这样,如您所见,我在指令之外显示了名称,当我更改它时它会更新。
<tr ng-repeat="item in report.criteria">
<td>
<h5 ng-bind="item.name"></h5>
<span criteria-description="item"></span>
</td>
</tr>
您不需要解析。
试试这个..
scope.$watch(attrs.criteriaDescription, function (newValue, oldValue) {
var desc = 'You have a name of ' + newValue.name;
element.html(desc);
}, true);
在您提供的代码片段中,
var item = $parse(attrs.criteriaDescription)(scope);
这将在 link 函数开始时进行计算。
由于这个值只计算一次,所以不会改变。
因此您的手表没有被触发。
为什么需要自定义指令?就这样不行吗?
<tr ng-repeat="item in report.criteria">
<td>
<h5 ng-bind="item.name"></h5>
<span>You have a name of {{item.name}}</span>
</td>
</tr>
由于范围是隔离的,您可以使用访问 scope.items
并使用 $watchCollection
:
观察它的变化
angular.module('app').directive('criteriaDescription', [function () {
'use strict';
return {
scope: {
item: '=criteriaDescription'
},
link: function (scope, element, attrs) {
scope.$watchCollection('item', function (newValue, oldValue) {
var desc = 'You have a name of ' + newValue.name;
element.html(desc);
});
}
};
}]);
演示: http://plnkr.co/edit/hSrRyKM8LQbp5evbaywD?p=preview
您还可以使用 $watch
和第三个参数 true
来强制进行深度对象比较以检测更改:
scope.$watch('item', function (newValue, oldValue) {
var desc = 'You have a name of ' + newValue.name;
element.html(desc);
}, true);
我确信这将是其中的一件事 "duh",但我似乎无法弄清楚为什么我的手表在我的指令中会触发。
我有一个指令要写出一些关于有问题的项目。我试图通过
引用该项目scope: {
item: '=criteriaDescription'
}
以及使用 $parse,所以我不必有一个独立的范围,两者似乎都不起作用,因为我的 'changed' 代码没有被调用。这是我的指令
angular.module('app').directive('criteriaDescription', ['$parse', function ($parse) {
'use strict';
return {
restrict: 'A',
link: function (scope, element, attrs) {
var item = $parse(attrs.criteriaDescription)(scope);
// generate a description for this criteria item, based on values and options
scope.$watch(function () {
return item;
}, function (newValue, oldValue) {
var desc = 'You have a name of ' + newValue.name;
element.html(desc);
});
}
};
}]);
我使用该指令的 HTML 看起来像这样,如您所见,我在指令之外显示了名称,当我更改它时它会更新。
<tr ng-repeat="item in report.criteria">
<td>
<h5 ng-bind="item.name"></h5>
<span criteria-description="item"></span>
</td>
</tr>
您不需要解析。
试试这个..
scope.$watch(attrs.criteriaDescription, function (newValue, oldValue) {
var desc = 'You have a name of ' + newValue.name;
element.html(desc);
}, true);
在您提供的代码片段中,
var item = $parse(attrs.criteriaDescription)(scope);
这将在 link 函数开始时进行计算。
由于这个值只计算一次,所以不会改变。
因此您的手表没有被触发。
为什么需要自定义指令?就这样不行吗?
<tr ng-repeat="item in report.criteria">
<td>
<h5 ng-bind="item.name"></h5>
<span>You have a name of {{item.name}}</span>
</td>
</tr>
由于范围是隔离的,您可以使用访问 scope.items
并使用 $watchCollection
:
angular.module('app').directive('criteriaDescription', [function () {
'use strict';
return {
scope: {
item: '=criteriaDescription'
},
link: function (scope, element, attrs) {
scope.$watchCollection('item', function (newValue, oldValue) {
var desc = 'You have a name of ' + newValue.name;
element.html(desc);
});
}
};
}]);
演示: http://plnkr.co/edit/hSrRyKM8LQbp5evbaywD?p=preview
您还可以使用 $watch
和第三个参数 true
来强制进行深度对象比较以检测更改:
scope.$watch('item', function (newValue, oldValue) {
var desc = 'You have a name of ' + newValue.name;
element.html(desc);
}, true);