Primeiro, observe que essa exceção só será lançada quando você estiver executando seu aplicativo no modo dev (que é o caso por padrão no beta-0): se você chamar enableProdMode()
ao inicializar o aplicativo, ele não será lançado ( consulte plunk atualizado ).
Segundo, não faça isso porque essa exceção está sendo lançada por uma boa razão: em resumo, quando no modo dev, todas as rodadas de detecção de alterações são seguidas imediatamente por uma segunda rodada que verifica se nenhuma ligação foi alterada desde o final da primeira, pois isso indica que as alterações estão sendo causadas pela própria detecção de alterações.
Na sua conexão, a ligação {{message}}
é alterada pela sua chamada para setMessage()
, o que ocorre no ngAfterViewInit
gancho, que ocorre como parte da curva inicial de detecção de alterações. Porém, isso por si só não é problemático - o problema é que setMessage()
altera a ligação, mas não aciona uma nova rodada de detecção de alterações, o que significa que essa alteração não será detectada até que alguma futura rodada de detecção de alterações seja acionada em outro lugar.
O ponto principal: tudo o que altera uma ligação precisa acionar uma rodada de detecção de alterações quando isso ocorre.
Atualize em resposta a todos os pedidos de um exemplo de como fazer isso : a solução do @ Tycho funciona, assim como os três métodos na resposta que o @MarkRajcok apontou. Mas, francamente, todos eles se sentem feios e errados para mim, como o tipo de hacks que nos acostumamos a usar no ng1.
Para ter certeza, existem ocasionais circunstâncias em que estes hacks são apropriados, mas se você estiver usando-os em qualquer coisa mais do que um muito ocasional, é um sinal de que você está lutando contra a estrutura, em vez de abraçar plenamente a sua natureza reativa.
IMHO, um "Angular2 maneira" mais idiomática de abordar isso é algo ao longo das linhas de: ( plunk )
@Component({
selector: 'my-app',
template: `<div>I'm {{message | async}} </div>`
})
export class App {
message:Subject<string> = new BehaviorSubject('loading :(');
ngAfterViewInit() {
this.message.next('all done loading :)')
}
}
ExpressionChangedAfterItHasBeenCheckedError
erro explica o comportamento em grandes detalhes.