Você precisa estar ciente de como o AngularJS funciona para entendê-lo.
Ciclo de resumo e escopo $
Em primeiro lugar, o AngularJS define um conceito do chamado ciclo de digestão . Esse ciclo pode ser considerado como um loop, durante o qual o AngularJS verifica se há alguma alteração em todas as variáveis observadas por todos os $scope
s. Portanto, se você $scope.myVar
definiu em seu controlador e essa variável foi marcada para ser observada , você está dizendo implicitamente ao AngularJS para monitorar as alterações myVar
em cada iteração do loop.
Uma pergunta natural de acompanhamento seria: tudo está ligado à $scope
observação? Felizmente não. Se você observasse as alterações em todos os objetos do seu $scope
computador, rapidamente um ciclo de digestão levaria séculos para ser avaliado e você enfrentaria problemas de desempenho rapidamente. É por isso que a equipe do AngularJS nos deu duas maneiras de declarar alguma $scope
variável como sendo observada (leia abaixo).
O $ watch ajuda a ouvir as alterações do escopo $
Existem duas maneiras de declarar uma $scope
variável como sendo observada.
- Ao usá-lo em seu modelo através da expressão
<span>{{myVar}}</span>
- Adicionando-o manualmente através do
$watch
serviço
Anúncio 1) Esse é o cenário mais comum e tenho certeza de que você já o viu antes, mas não sabia que isso criou um relógio em segundo plano. Sim, tinha! O uso de diretivas AngularJS (como ng-repeat
) também pode criar relógios implícitos.
Anúncio 2) É assim que você cria seus próprios relógios . $watch
O serviço ajuda a executar algum código quando algum valor anexado ao $scope
foi alterado. Raramente é usado, mas às vezes é útil. Por exemplo, se você deseja executar algum código sempre que 'myVar' for alterado, faça o seguinte:
function MyController($scope) {
$scope.myVar = 1;
$scope.$watch('myVar', function() {
alert('hey, myVar has changed!');
});
$scope.buttonClicked = function() {
$scope.myVar = 2; // This will trigger $watch expression to kick in
};
}
$ apply permite integrar alterações ao ciclo de resumo
Você pode pensar na $apply
função como um mecanismo de integração . Veja bem, toda vez que você altera alguma variável observada anexada$scope
diretamente ao objeto, o AngularJS saberá que a alteração ocorreu. Isso ocorre porque o AngularJS já sabia monitorar essas alterações. Portanto, se isso acontecer no código gerenciado pela estrutura, o ciclo de resumo continuará.
No entanto, às vezes você deseja alterar algum valor fora do mundo do AngularJS e ver as mudanças se propagarem normalmente. Considere isso - você tem um $scope.myVar
valor que será modificado no $.ajax()
manipulador de um jQuery . Isso acontecerá em algum momento no futuro. O AngularJS não pode esperar que isso aconteça, pois não foi instruído a esperar no jQuery.
Para resolver isso, $apply
foi introduzido. Permite iniciar explicitamente o ciclo de digestão. No entanto, você deve usar isso apenas para migrar alguns dados para o AngularJS (integração com outras estruturas), mas nunca use esse método combinado ao código AngularJS regular, pois o AngularJS gerará um erro.
Como tudo isso está relacionado ao DOM?
Bem, você realmente deve seguir o tutorial novamente, agora que sabe tudo isso. O ciclo de resumo garantirá que a interface do usuário e o código JavaScript permaneçam sincronizados, avaliando todos os observadores conectados a todos os $scope
s, desde que nada mude. Se não ocorrer mais alterações no loop de digestão, será considerado concluído.
Você pode anexar objetos ao $scope
objeto explicitamente no Controller ou declarando-os no {{expression}}
formulário diretamente na visualização.
Espero que ajude a esclarecer alguns conhecimentos básicos sobre tudo isso.
Leituras adicionais:
No AngularJS, atualizamos nossos modelos e nossas visualizações / modelos atualizam o DOM "automaticamente" (por meio de diretivas internas ou personalizadas).
$ apply e $ watch, ambos métodos de Scope, não estão relacionados ao DOM.
A página Conceitos (seção "Tempo de execução") tem uma boa explicação do loop $ digest, $ apply, da fila $ evalAsync e da lista de observação $. Aqui está a figura que acompanha o texto:
Qualquer código que tenha acesso a um escopo - normalmente controladores e diretivas (suas funções de link e / ou controladores) - pode configurar uma " watchExpression " que o AngularJS avaliará em relação a esse escopo. Essa avaliação ocorre sempre que o AngularJS entra no loop $ digest (em particular, no loop "$ watch list"). Você pode observar propriedades individuais do escopo, definir uma função para observar duas propriedades juntas, observar o comprimento de uma matriz, etc.
Quando as coisas acontecem "dentro do AngularJS" - por exemplo, você digita em uma caixa de texto que possui a conexão de dados bidirecional do AngularJS ativada (ou seja, usa o modelo ng), um retorno de chamada $ http é acionado etc. - $ apply já foi chamado, então nós está dentro do retângulo "AngularJS" na figura acima. Todas as watchExpressions serão avaliadas (possivelmente mais de uma vez - até que nenhuma alteração adicional seja detectada).
Quando as coisas acontecem "fora do AngularJS" - por exemplo, você usou bind () em uma diretiva e, em seguida, esse evento é disparado, resultando na chamada de retorno de chamada ou em alguns retornos de chamada registrados pelo jQuery - ainda estamos no retângulo "Nativo". Se o código de retorno de chamada modificar qualquer coisa que qualquer $ watch esteja assistindo, chame $ apply para entrar no retângulo AngularJS, fazendo com que o loop $ digest seja executado e, portanto, o AngularJS notará a alteração e fará sua mágica.
fonte
scope.$apply(scope.model)
, não entendo quais dados são transferidos e como são transferidos para o local certo no modelo?scope.$apply(scope.model)
irá simplesmente avaliarscope.model
como uma expressão Angular e inserir um loop $ digest. No artigo que vocêscope.$apply()
mencionou , provavelmente seria suficiente, já que o modelo já está sendo monitorado. A função stop () está atualizando o modelo (acredito que toUpdate é uma referência ao scope.model) e, em seguida, $ apply é chamado.$watch
na página e o segundo link está quebrado - a partir de agora, de qualquer maneira). Dolorosamente, as versões do arquivo não armazenavam em cache qualquer processo assíncrono que criou o conteúdo.AngularJS estende isso loop de eventos , criando algo chamado
AngularJS context
.$ watch ()
Toda vez que você vincula algo na interface do usuário, insere um
$watch
em uma$watch
lista .Aqui temos
$scope.user
, que está vinculado à primeira entrada, e temos$scope.pass
, que está vinculada à segunda entrada. Fazendo isso, adicionamos dois$watch
es à$watch
lista .Quando nosso modelo é carregado, também conhecido como AKA, na fase de vinculação, o compilador procurará todas as diretivas e criará todas as
$watch
es necessárias.AngularJS fornece
$watch
,$watchcollection
e$watch(true)
. Abaixo está um diagrama detalhado que explica todas as três tiradas dos observadores em profundidade .http://jsfiddle.net/2Lyn0Lkb/
$digest
cicloQuando o navegador recebe um evento que pode ser gerenciado pelo contexto AngularJS, o
$digest
loop é acionado. Esse loop é feito de dois loops menores. Um processa a$evalAsync
fila e o outro processa o$watch list
. O$digest
loop irá percorrer a lista$watch
que temosAqui temos apenas um
$watch
porque o ng-click não cria nenhum relógio.Nós pressionamos o botão.
$digest
loop será executado e solicitará a cada $ watch alterações.$watch
que estava observando alterações no $ scope.name relata uma alteração, forçará outro$digest
loop.$digest
loop. Isso significa que toda vez que escrevermos uma letra em uma entrada, o loop será executado verificando todas as$watch
páginas desta página.$ apply ()
Se você ligar
$apply
quando um evento for disparado, ele passará pelo contexto angular, mas se você não o chamar, ele será executado fora dele. É tão fácil quanto isso.$apply
chamará o$digest()
loop internamente e iterará em todos os relógios para garantir que o DOM seja atualizado com o valor recém-atualizado.O
$apply()
método acionará observadores em toda a$scope
cadeia, enquanto o$digest()
método acionará apenas observadores na corrente$scope
e na suachildren
. Quando nenhum dos$scope
objetos superiores precisar saber sobre as alterações locais, você poderá usá-lo$digest()
.fonte
Eu achei muito vídeos em profundidade que abrangem
$watch
,$apply
,$digest
e digerir ciclos em:AngularJS - Entendendo o Watcher, $ watch, $ watchGroup, $ watchCollection, ng-change
AngularJS - Entendendo o ciclo de digestão (fase de digestão ou processo de digestão ou loop de digestão)
Tutorial do AngularJS - Compreendendo $ apply e $ digest (em profundidade)
A seguir, são apresentados alguns slides usados nesses vídeos para explicar os conceitos (por precaução, se os links acima foram removidos / não estão funcionando).
Na imagem acima, "$ scope.c" não está sendo observado, pois não é usado em nenhuma das ligações de dados (na marcação). Os outros dois (
$scope.a
e$scope.b
) serão assistidos.Na imagem acima: Com base no respectivo evento do navegador, o AngularJS captura o evento, realiza o ciclo de digestão (passa por todos os relógios em busca de alterações), executa funções de relógio e atualiza o DOM. Se não houver eventos no navegador, o ciclo de resumo pode ser acionado manualmente usando
$apply
ou$digest
.Mais sobre
$apply
e$digest
:fonte
Existem
$watchGroup
e$watchCollection
também. Especificamente,$watchGroup
é realmente útil se você deseja chamar uma função para atualizar um objeto que possui várias propriedades em uma visualização que não é um objeto dom, por exemplo, outra visualização em canvas, WebGL ou solicitação do servidor.Aqui, o link da documentação .
fonte
$watchCollection
mas vejo que você já fez. Aqui está a documentação sobre isso no site do AngularJS. Eles fornecem um visual muito bonito da$watch
profundidade. Observe que as informações estão próximas à parte inferior da página.Apenas termine de ler TODAS as anteriores, chatas e sonolentas (desculpe, mas é verdade). Muito técnico, detalhado, detalhado e seco. Por que estou escrevendo? Como o AngularJS é massivo, muitos conceitos interconectados podem deixar qualquer pessoa louca. Muitas vezes me perguntei: não sou inteligente o suficiente para entendê-las? Não! É porque tão poucos conseguem explicar a tecnologia em uma linguagem for-dummie sem todas as terminologias! Ok, deixe-me tentar:
1) São coisas orientadas a eventos. (Eu ouço a risada, mas continue a ler)
Se você não sabe o que é orientado a eventos, pense em colocar um botão na página, conecte-o com uma função usando "on-click", esperando que os usuários cliquem nele para acionar as ações que você planta dentro do função. Ou pense em "gatilho" do SQL Server / Oracle.
2) $ watch está "ao clicar".
O que é especial é que são necessárias duas funções como parâmetros, a primeira fornece o valor do evento, a segunda leva o valor em consideração ...
3) $ digest é o chefe que verifica incansavelmente , bla-bla-bla, mas um bom chefe.
4) $ apply fornece o caminho quando você deseja fazê-lo manualmente , como uma prova de falha (caso o clique não aconteça, você o força a executar.)
Em um restaurante,
- GARÇONS
devem receber pedidos dos clientes, isso é
- GERENTE correndo para garantir que todos os garçons estejam acordados, respondendo a qualquer sinal de alterações dos clientes. Isto é
$digest()
- O PROPRIETÁRIO tem o poder final de conduzir todos, mediante solicitação, este é
$apply()
fonte