#angularjs
#angularjs
Вопрос:
Мне нужна помощь, чтобы понять концепцию «просмотра» изменений объекта и обновления его в представлении.
В моем конкретном случае объект инициализируется с помощью разрешения представления, а затем присваивается параметру области видимости с помощью контроллера.
Я ожидаю, что каким-то образом, если я снова обновлю исходный объект, он должен изменить значение, распечатанное в представлении
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
template: 'hello {{ user.name }}',
controller: 'userController',
resolve: {
user: function () {
return {name: 'john'}
}
}
}).
otherwise({
redirectTo: '/'
});
}]);
myApp.controller('userController', function($scope, user) {
$scope.user = user;
// I thought the object is supposed to be watched by reference but it is not
user = {name: 'doe'}
});
плунжер: http://plnkr.co/edit/w7woYVYB6GwCiJpWGWB4?p=preview
Пожалуйста, скажите мне, что я делаю не так и как это исправить
Редактировать для получения дополнительных разъяснений:
Я виноват, что пропустил причину всего этого. Мое решение на самом деле выглядит так:
resolve: {
user: function () {
return userService.get();
}
}
Как вы можете видеть, я возвращаю объект для разрешения (который является свойством, определенным внутри UserService). Теперь я надеюсь, что если я смогу просто вызвать UserService.update(); в моем контроллере тогда каким-то образом $scope.user, все еще указывающий на тот же объект, обновится автоматически. Думаю, нет….
userService.update();
Комментарии:
1. Я обновил свой ответ, чтобы показать вам, как реализовать функциональность $ watch.
Ответ №1:
Проблема проста. $scope.user указывает на объект, отличный от того, на который пользователь указывает после вызова user = {name: 'doe'}
Исправление является одним из них
$scope.user={name:'doe';}
или
$scope.user.name='doe';
Обновление: если служба обновляет данные, а контроллеры хотят получать уведомления, подход, который следует предпринять, заключается в том, чтобы вызывать события в $ rootSscope.
В сервисе вы можете сделать
$rootScope.$emit('event.userUpdate',{user:user});
В контроллере вы можете перехватить это событие с помощью
$rootScope.$on('event.userUpdate',function(evt, args) {
//args should have he update user data, to rebind.
});
Комментарии:
1. На самом деле, проблема в том, что этот пользователь должен обновляться через службу, поэтому я бы предпочел как-то просто обновить пользователя, и область будет отражать это, какое-либо решение вообще?
2. Пока служба обновляет один и тот же пользовательский объект, все будет работать нормально.
3. Спасибо, Чандермани, я обновил свой вопрос для получения дополнительной информации, пожалуйста, дайте мне знать, если я недостаточно ясен.
4. Служба angularjs является заводской функцией и, как таковая, запускается только один раз (при создании экземпляра контроллера). Вы можете реализовать функцию $watch для отслеживания, когда происходит изменение, а затем снова вызвать сервисную функцию.
5. Чандермани совершенно прав. Вероятно, его подход — это то, что вы хотите. Вы запускаете событие $ emit или $ broadcast, когда пользователь изменился, и во всех заинтересованных контроллерах следите за изменениями с помощью $ on и реагируйте соответствующим образом.
Ответ №2:
Если я правильно понимаю, чего вы хотите достичь, то это должно сработать:
myApp.controller('userController', function($scope, user) {
$scope.user = user;
$scope.user = {name: 'doe'}
});
Обратите внимание на строку: $scope.user = {name: 'doe'}
вместо user = {name: 'doe'}
Вот ваш модифицированный плунжер.
Когда вы редактировали свой вопрос, я также обновил свой ответ, чтобы показать вам, как реализовать функциональность $ watch. В этом случае мы наблюдаем за изменением переменной willChange и соответствующим изменением пользователя. Здесь плунжер.
Комментарии:
1. спасибо, zszep, я обновил свой вопрос дополнительной информацией