Выставленный литерал объекта службы Angular не обновляется?

0

Я работаю в Angular. Я создал простой сервис, чтобы проиллюстрировать проблему, которую я вижу. Когда кто-то вызывает метод setProfile для этой службы, моя цель - установить "профиль" в новый литерал объекта, который содержит новые значения свойств. Однако, когда я это делаю, не появляется, что пользователи этой службы могут видеть обновления. Другими словами, они видят старый объект "профиль", а не новый. Однако, если я просто обновляю отдельные свойства вместо того, чтобы присваивать "профиль" новому литералу объекта, они прекрасно видят обновления. Я очень смущен.

Этот код работает (т.е. После вызова метода setProfile, потребители видят обновленные значения):

(function () {
angular.module('myApp').factory('myService', function () {

    var profile = {
        firstName: '',
        lastName: ''
    };

    var setProfile = function (firstName, lastName) {
        profile.firstName = firstName;
        profile.lastName = lastName;
    };

    return {
        setProfile: setProfile,
        profile: profile
    }
});
}());

Но это не работает (т.е. Когда я назначаю профиль новому литералу объекта, потребители не видят новый объект):

(function () {
angular.module('myApp').factory('myService', function () {

    var profile = {
        firstName: '',
        lastName: ''
    };

    var setProfile = function (firstName, lastName) {
        profile = {
            firstName: firstName,
            lastName: lastName
        };
    };

    return {
        setProfile: setProfile,
        profile: profile
    }
});
}());

Ниже приведен пример использования службы:

module.run(['$rootScope', 'currentUser', function ($rootScope, currentUser) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
    debugger;
    if (!currentUser.firstName == 'test') {
        return;
    }
});
}]);
Теги:

1 ответ

1
Лучший ответ

Это ожидается, потому что потребители profile имеют ссылку на исходный объект, который создается. Поэтому, если вы обновляете объект через profile.firstName = 'bob' вы обновляете один и тот же объект. Однако, когда вы устанавливаете профиль через profile = {firstname: 'bob'} вы создаете совершенно новый объект, когда используете фигурные скобки, а все пользователи первого объекта профиля не знают о новом.

Один из способов обойти это с $watch но обычно лучше избегать $watch если вы можете по соображениям производительности.

Что-то еще нужно иметь в виду, так это то, что все угловые фабрики/службы - это Singletons. Поэтому, когда вы новичок в Angular, вы можете ожидать, что новый currentUser вводится каждый раз, когда ваш контроллер запускается, когда на самом деле все инъекции ссылаются на один и тот же экземпляр currentUser.

  • 0
    Итак, переменные, которые указывают на литералы объекта, указывают на ссылку или значение? Если это по значению, то это будет иметь смысл, в противном случае это не так. Потому что, если это по ссылке, это означает, что моя фабрика вернула объект, который имеет свойство профиля, которое ссылается на внутреннее свойство, которое ссылается на литерал объекта. Таким образом, обновление внутреннего объекта профиля до нового объекта просто обновит ссылку. Я что-то пропустил?
  • 0
    Оба;) Может быть, это будет иметь больше смысла: stackoverflow.com/questions/518000/…
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню