Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
25
rated 0 times [  26] [ 1]  / answers: 1 / hits: 20850  / 10 Years ago, mon, april 14, 2014, 12:00:00

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



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



<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



Maybe the problem is with $watch, but everything seems to be ok. Any suggestions?



P.S. In real app I need to use the directive to do more complex text manipulation than just concatenation.


More From » html

 Answers
23

Set the third parameter of $watch (objectEquality) to 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.


[#71480] Friday, April 11, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
monica

Total Points: 308
Total Questions: 102
Total Answers: 109

Location: Saudi Arabia
Member since Sat, Aug 20, 2022
2 Years ago
;