Como se inscrever na alteração de propriedade ao usar a controller as
sintaxe?
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>
Respostas:
Apenas ligue o contexto relevante.
Exemplo: http://jsbin.com/yinadoce/1/edit
ATUALIZAR:
A resposta de Bogdan Gersak é, na verdade, meio equivalente, ambas as respostas tentam ser vinculadas
this
ao contexto certo. No entanto, achei sua resposta mais limpa.Dito isso, em primeiro lugar, você precisa entender a ideia subjacente a ela .
ATUALIZAÇÃO 2:
Para quem usa o ES6, ao usar,
arrow function
você obtém uma função com o contexto correto OOTB.Exemplo
fonte
$scope
para você é um tipo de serviço que fornece esse tipo de método.name
emreturn this.name;
refere-se ao nome do controlador ou a propriedade "name
" aqui?angular.bind
retorna uma função com um contexto delimitado (argumento # 1). No nosso caso, vinculamosthis
, que é a instância do controlador, à função (arg # 2), portanto,this.name
significa a propriedadename
da instância do controlador.Eu costumo fazer isso:
fonte
$scope.$watch
e usar essa função para retornar um valor do fechamento. Ainda tenho que encontrar outro exemplo disso, mas funciona e é o melhor. O motivo pelo qual não escolhi a resposta abaixo (ou seja$scope.$watch('test.name', function (value) {});
) é porque exigi que eu codificasse o nome do meu controlador no meu modelo ou no $ stateProvider do ui.router e qualquer alteração ocorreria sem querer interromper o observador.angular.bind
) é se você deseja vincularthis
ou simplesmente adicionar outra referência aothis
fechamento. Eles são funcionalmente equivalentes e, na minha experiência, esse tipo de escolha costuma ser um chamado subjetivo e o assunto de uma opinião muito forte.$scope.$watch( ()=> { return this.name' }, function(){} )
Flecha gorda para o resgate() => this.name
$scope.$watchCollection
e ainda obter osoldVal, newVal
parâmetros?Você pode usar:
Isso está trabalhando o JSFiddle com o seu exemplo.
fonte
Semelhante ao uso do "teste" de "TestCtrl como teste", conforme descrito em outra resposta, você pode atribuir a si mesmo seu escopo:
Dessa forma, você não está vinculado ao nome especificado no DOM ("TestCtrl como teste") e também evita a necessidade de vincular (isso) a uma função.
... para uso com o html original especificado:
fonte
$scope
é um serviço, por isso, se adicionarmos$scope.self = this
, em outro controlador, se fizermos o mesmo, o que acontecerá lá?AngularJs 1.5 suporta o $ ctrl padrão para a estrutura ControllerAs.
fonte
você pode realmente passar uma função como o primeiro argumento de um $ watch ():
O que significa que podemos retornar nossa referência this.name:
Leia um post interessante sobre o controlador Como tópico https://toddmotto.com/digging-into-angulars-controller-as-syntax/
fonte
Você pode usar o ciclo de vida do componente angular $ onChanges .
consulte a documentação aqui: https://docs.angularjs.org/guide/component na seção de aplicativos baseados em componentes
fonte
Escrever um $ watch na sintaxe ES6 não foi tão fácil quanto eu esperava. Aqui está o que você pode fazer:
fonte
NOTA : Isso não funciona quando o View e o Controller são acoplados em uma rota ou através de um objeto de definição de diretiva. O que é mostrado abaixo só funciona quando há um "SomeController as SomeCtrl" no HTML. Assim como Mark V. aponta no comentário abaixo, e assim como ele diz que é melhor fazer como Bogdan faz.
Eu uso:
var vm = this;
no início do controlador para tirar a palavra "isso" do meu caminho. Entãovm.name = 'Max';
e no relógio eureturn vm.name
. Eu uso o "vm" assim como o @Bogdan usa o "self". Essa var, seja "vm" ou "self", é necessária, pois a palavra "this" assume um contexto diferente dentro da função. (portanto, retornar this.name não funcionaria) E sim, você precisa injetar $ scope em sua bela solução "controller as" para alcançar $ watch. Consulte o Guia de estilo de John Papa: https://github.com/johnpapa/angularjs-styleguide#controllersfonte
Aqui está como você faz isso sem $ scope (e $ watch!) Os 5 principais erros - abuso de relógio
Se você estiver usando a sintaxe "controller as", é melhor e mais limpo evitar o uso do $ scope.
Aqui está o meu código no JSFiddle . (Estou usando um serviço para armazenar o nome, caso contrário, os métodos set e get do ES5 Object.defineProperty causam chamadas infinitas.
fonte