Обновление 'this' Свойство контекста внутри $Promise в службе Angular JS
У меня есть функция, используемая в моей службе, которая определяется как:
var getData = function() {
return anotherService.getData().$promise;
};
и a this
, которые я манипулирую во всей службе.
this.someProperty = 'a string';
Я вызываю указанную выше функцию в разделе возврата моей службы:
return{
updateProperty: function(){
getData().then(function(data){
this.someProperty = data;
});
}
}
В приведенном выше примере я получаю связанную с this is undefined
ошибку в моей консоли браузера. Я предполагаю, что это связано с тем, что разрешенный $promise
является вызовом AJAX и this
используется вне контекста. Каким образом можно управлять свойством this
с использованием возвращенных данных из вызова AJAX в этом экземпляре?
Ответы
Ответ 1
если вы манипулируете this
на протяжении всей своей службы, назначьте ее переменной типа var self = this
. Проблема в том, что this
является контекстом функции и может быть изменен другим кодом с помощью fn.call(context)
или fn.apply(context, args)
. Таким образом, он может быть различным в рамках любой заданной функции.
Поэтому просто назначьте его некоторой переменной и используйте ее:
var self = this;
return {
updateProperty: function(){
getData().then(function(data){
self.someProperty = data;
});
}
};
Ответ 2
Самый простой способ - использовать функцию bind. Эта функция устанавливает контекст 'this' для вызова функции. Таким образом, в вашем случае вам придется использовать его дважды, чтобы заполнить соответствующий 'this'.
return{
updateProperty: function(){
getData().then((function(data){
this.someProperty = data;
}).bind(this));
}
}
Это делается для того, чтобы обработчик, который вы передали обещанию, выполнялся с исходным 'this' (переданным в updateProperty). Теперь, чтобы передать правильное значение 'this' функции updateProperty, вы должны в своем контроллере:
(myService.updateProperty.bind(this))();
Существует множество версий привязки, включая привязку всей службы. Кроме того, посмотрите на lodash для расширения функций.
Я подготовил маленькую ручку, чтобы продемонстрировать это. Он охватывает то, что я перечислил выше, плюс еще одно важное замечание. Когда вы используете setTimeout, обработчик вызывается в глобальном контексте (в данном случае "окно" ), поэтому я добавил третье связывание, чтобы убедиться, что 'this' имеет значение внутри обработчика тайм-аута. Я также добавил различные вызовы приращения количества, чтобы продемонстрировать, что 'this' - это то же самое значение на этом пути.
Если это повторяющийся сценарий, вы можете передать либо целевой объект (а затем использовать обработчик, чтобы знать, что он был обновлен), либо обработчик (который также требует привязки). Я также добавил примеры для этих сценариев.
Последнее слово, вызов, применение и привязка являются ключевыми для javascript и заслуживают изучения. Поместите некоторое время в это и проведите свой путь из контекста ад.