Как подписаться на изменение свойства при использовании controller as
синтаксиса?
controller('TestCtrl', function ($scope) {
this.name = 'Max';
this.changeName = function () {
this.name = new Date();
}
// not working
$scope.$watch("name",function(value){
console.log(value)
});
});
<div ng-controller="TestCtrl as test">
<input type="text" ng-model="test.name" />
<a ng-click="test.changeName()" href="#">Change Name</a>
</div>
Ответы:
Просто свяжите соответствующий контекст.
Пример: http://jsbin.com/yinadoce/1/edit
ОБНОВИТЬ:
Ответ Богдана Герсака фактически эквивалентен, оба ответа пытаются связать
this
с правильным контекстом. Однако я нашел его ответ чище.Сказав это, прежде всего, вы должны понять основную идею, стоящую за этим .
ОБНОВЛЕНИЕ 2:
Для тех, кто использует ES6, с помощью
arrow function
вы получите функцию с правильным контекстом OOTB.пример
источник
$scope
для вас это своего рода услуга, которая предоставляет такие методы.name
вreturn this.name;
ссылается на имя контроллера или свойства «name
» здесь?angular.bind
возвращает функцию с ограниченным контекстом (arg # 1). В нашем случае мы привязываемthis
, который является экземпляром контроллера, к функции (arg # 2), чтоthis.name
означает свойствоname
экземпляра контроллера.Я обычно делаю это:
источник
$scope.$watch
и использовании этой функции для возврата значения из замыкания. Я еще не сталкивался с другим примером этого, но он работает и является лучшим. Причина, по которой я не выбрал ответ ниже (т.$scope.$watch('test.name', function (value) {});
Е.), Заключается в том, что он требовал, чтобы я жестко запрограммировал то, что я назвал своим контроллером, в своем шаблоне или в $ stateProvider ui.router, и любое изменение там непреднамеренно сломало бы наблюдателя.angular.bind
) заключается в том, хотите ли вы связатьthis
или просто добавить другую ссылкуthis
в закрытии. Они функционально эквивалентны, и, по моему опыту, такой выбор часто является субъективным вызовом и вопросом очень сильного мнения.$scope.$watch( ()=> { return this.name' }, function(){} )
Жирная стрела на помощь() => this.name
$scope.$watchCollection
и все еще получитьoldVal, newVal
параметры?Ты можешь использовать:
Это работает JSFiddle с вашим примером.
источник
Аналогично использованию «test» из «TestCtrl в качестве теста», как описано в другом ответе, вы можете назначить «self» вашу область:
Таким образом, вы не привязаны к имени, указанному в DOM («TestCtrl as test»), и вы также избегаете необходимости .bind (this) с функцией.
... для использования с указанным оригинальным html:
источник
$scope
Это сервис, поэтому, если мы добавим$scope.self = this
, то в другой контроллер, если мы сделаем то же самое, что там произойдет?AngularJs 1.5 поддерживает $ ctrl по умолчанию для структуры ControllerAs.
источник
вы можете передать функцию в качестве первого аргумента $ watch ():
Это означает, что мы можем вернуть нашу ссылку this.name:
Прочитайте интересный пост о контроллере как тему https://toddmotto.com/digging-into-angulars-controller-as-syntax/
источник
Вы можете использовать $ onChanges угловой жизненный цикл компонента.
обратитесь к документации здесь: https://docs.angularjs.org/guide/component под компонент на основе применения раздела
источник
Написание $ watch в синтаксисе ES6 оказалось не так просто, как я ожидал. Вот что вы можете сделать:
источник
ПРИМЕЧАНИЕ . Это не работает, когда View и Controller связаны в маршруте или через объект определения директивы. То, что показано ниже, работает только тогда, когда в HTML есть «SomeController as SomeCtrl». Точно так же, как Марк В. указывает в комментарии ниже, так же, как он говорит, что лучше делать, как Богдан.
Я использую:
var vm = this;
в начале контроллера, чтобы убрать слово «это» с моего пути. Тогдаvm.name = 'Max';
и в часы яreturn vm.name
. Я использую «vm» так же, как @Bogdan использует «self». Это var, будь то «vm» или «self», необходимо, поскольку слово «this» имеет другой контекст внутри функции. (поэтому возвращение this.name не сработает) И да, вам нужно ввести $ scope в ваше красивое решение "controller as", чтобы достичь $ watch. См. Руководство по стилю Джона Папы: https://github.com/johnpapa/angularjs-styleguide#controllersисточник
Вот как это сделать без $ рамки (и $ часов!) Топ 5 ошибок - Злоупотребления часов
Если вы используете синтаксис «контроллер как», лучше и чище избегать использования $ scope.
Вот мой код в JSFiddle . (Я использую сервис для хранения имени, в противном случае методы set и get объекта ES5 Object.defineProperty вызывают бесконечные вызовы.
источник