javascript AngularJS 自定义指令 $watch 不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23050807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS custom directive $watch not working
提问by VIK
I am creating a demo application with two controllers communicating through a service containing some data. It is a kind of contacts book. A user can edit selected person from the list.
我正在创建一个演示应用程序,其中两个控制器通过包含一些数据的服务进行通信。它是一种通讯录。用户可以从列表中编辑选定的人员。
The data is stored in array of objects and I use a custom directive to perform some manipulations with that objects' text properties.
数据存储在对象数组中,我使用自定义指令对该对象的文本属性执行一些操作。
The problem is that a text rendered in the list using the custom directive is not updated on model change (when typing something in name fields) while a text that is placed using {{}} changes while typing.
问题是使用自定义指令在列表中呈现的文本不会在模型更改时更新(在名称字段中键入内容时),而使用 {{}} 放置的文本在键入时会更改。
Here is a sample showing a problem:
这是一个显示问题的示例:
js
js
var contacts = angular.module('contacts', []);
contacts.service('database', ['$rootScope', function ($rootScope) {
return {
db : [
{person:{fName:"John", lName:"Williams"}, phone:"11111111111"},
{person: {fName:"Sara", lName:"Lewis"}, phone:"222222222"},
{person: {fName:"Lana", lName:"Watson"}, phone:"33333333333"},
{person: {fName:"John", lName:"Smith"}, phone:"4444444444"}
],
selectedPerson : null,
setSelected : function (i) {
this.selectedPerson = i;
$rootScope.$broadcast('selected');
}
}
}]);
contacts.controller("listCtrl", function($scope, database) {
$scope.list = database.db;
$scope.getSelected = function() {
return database.selectedPerson;
};
$scope.setSelected = function(i) {
database.setSelected(i);
};
});
contacts.controller("editorCtrl", function($scope, database) {
$scope.editing = database.selectedPerson;
$scope.$on('selected', function(event) {
$scope.editing = database.selectedPerson;
});
});
contacts.directive('personName', function() {
return {
restrict: 'AEC',
scope:{
personName: '='
},
link: function(scope, elem, attrs) {
scope.$watch(function(){return scope.personName;}, function(obj) {
var fullName = obj.fName + " " + obj.lName;
elem.text(fullName);
});
}
};
});
html
html
<div ng-app="contacts">
<div class='list' ng-controller="listCtrl">
<div ng-repeat="i in list"
ng-click="$parent.setSelected(i)"
ng-class="{'sel': ($parent.getSelected() === i)}">
<span person-name="i.person"></span>, {{i.phone}}
</div>
</div>
<div class='edit' ng-controller="editorCtrl">
First name: <input type="text" ng-model='editing.person.fName'> <br>
Last name: <input type="text" ng-model='editing.person.lName'> <br>
Phone: <input type="text" ng-model='editing.phone'> <br>
</div>
</div>
Working demo: http://cssdeck.com/labs/ejnhuqf9
工作演示:http: //cssdeck.com/labs/ejnhuqf9
Maybe the problem is with $watch, but everything seems to be ok. Any suggestions?
也许问题出在 $watch 上,但似乎一切正常。有什么建议?
P.S. In real app I need to use the directive to do more complex text manipulation than just concatenation.
PS 在实际应用程序中,我需要使用指令来进行更复杂的文本操作,而不仅仅是连接。
回答by j.wittwer
Set the third parameter of $watch(objectEquality) to true:
将$watch(objectEquality)的第三个参数设置为 true:
scope.$watch(function(){return scope.personName;}, function(obj) {
var fullName = obj.fName + " " + obj.lName;
elem.text(fullName);
}, true);
You might want to change the name of the property to person, to remind yourself that it is the entire object, not just a string name.
您可能希望将属性名称更改为 person,以提醒自己它是整个对象,而不仅仅是字符串名称。