Por que o Angular não atualiza o escopo aqui?

Sou muito novo no Angular e estou usando o firebase como meu back-end. Eu estava esperando que alguém pudesse depurar esse problema. Quando eu vou pela primeira vez à minha página www.mywebsite.com/#defaultHash, os dados não são carregados no DOM, depois de visitar outro link de hash e voltar.

Meu controlador é assim:

/* initialize data */ var fb = new Firebase('https://asdf.firebaseio.com/'); /* set data to automatically update on change */ fb.on('value', function(snapshot) { var data = snapshot.val(); $scope.propertyConfiguration = data.products; console.log($scope.propertyConfiguration); console.log("Data retrieved"); }); /* save data on button submit */ $scope.saveConfigs = function(){ var setFBref = new Firebase('https://asdf.firebaseio.com/products'); setFBref.update($scope.propertyConfiguration); console.log("configurations saved!"); }; 

Eu tenho 3 rotas hash dizer “Shared”, “Registro” e “Home” com o contrário.redirectPara definir como “Shared”. (Todos eles usam este controlador) Aqui está o erro que ocorre: (todos os “links” são href = ” #hashWhereever “)

1) Vá para website.com/#Shared ou apenas atualize. Registros do console $ scope.propertyConfiguration e “Data Retrieved”. DOM não mostra nada.

2) Clique para website.com/#Registration , o console registra os dados do escopo $ corretamente, o DOM é carregado corretamente.

3) Clique novamente em website.com/#Shared , o console registra os dados do escopo $ corretamente, mas desta vez o DOM carrega corretamente.

4) Atualize corretamente atualmente website.com/#Shared carregado. Elementos DOM desaparecem.

Como $ scope.data está correto em todos os casos aqui, o Angular não deve garantir que o DOM reflita o modelo corretamente? Por que é que o DOM carrega corretamente somente quando eu estou clicando para a página de outro link.

Eu posso “consertar” isso adicionando window.location.hash = “Shared”, mas isso gera uma enorme quantidade de erros no console.

CORRIGIDO : (sorta)

A function $ scope. $ Apply () força a visão a sincronizar com o modelo. Eu mesmo responderia a essa pergunta e a fecharia, mas ainda estou me perguntando por que a exibição não é carregada corretamente quando eu atribuo corretamente um valor a $ scope. Se a “verificação suja” do Angular verificar sempre que houver a possibilidade de o modelo ter sido alterado, não atribuir um valor ao superqualificado do escopo $?

Angular não tem como saber que você atribuiu um valor a $ scope.variable. Não há mágica aqui. Quando você executa uma diretiva (ng-click / ng-submit) ou funções internas Angular, todas elas chamam $ apply () e acionam um resumo (uma verificação dos sinalizadores sujos e da rotina de atualização).

Uma abordagem possivelmente mais segura do que $ apply seria usar $ timeout. Atualmente, se você chamar uma opção de gravação no Firebase, poderá triggersr de forma síncrona um ouvinte de evento (child_added, child_changed, value, etc). Isso pode fazer com que você chame $ apply enquanto ainda estiver em um escopo $ apply. Se você fizer isso, um erro será lançado. $ timeout ignora isso.

Veja esta pergunta SO para um pouco mais sobre o tema de digest e $ timeout.

Este documento no Angular Developer Guide cobre como funciona a compilation ; muito grande fundo lido para qualquer dev Angular grave.

Além disso, você pode poupar bastante energia usando as associações oficiais do Firebase para Angular , que já levam em consideração todos esses detalhes de implementação.

Nota vagamente relacionada: Em um futuro não muito distante, o Angular será capaz de aproveitar a mágica do Object.observe para lidar com essas atualizações.