Não há equivalente a $scope.emit()
ou $scope.broadcast()
em Angular?
Conheço a EventEmitter
funcionalidade, mas, pelo que entendi, isso apenas emitirá um evento para o elemento HTML pai.
E se eu precisar me comunicar entre fx. irmãos ou entre um componente na raiz do DOM e um elemento aninhado em vários níveis de profundidade?
Respostas:
Não há equivalente para
$scope.emit()
ou$scope.broadcast()
do AngularJS. O EventEmitter dentro de um componente se aproxima, mas, como você mencionou, ele emitirá apenas um evento para o componente pai imediato.No Angular, existem outras alternativas que tentarei explicar abaixo.
As ligações @Input () permitem que o modelo de aplicativo seja conectado em um gráfico de objeto direcionado (raiz às folhas). O comportamento padrão da estratégia do detector de alterações de um componente é propagar todas as alterações em um modelo de aplicativo para todas as ligações de qualquer componente conectado.
Lado: Existem dois tipos de modelos: View Models e Application Models. Um modelo de aplicativo é conectado através de ligações @Input (). Um modelo de exibição é apenas uma propriedade de componente (não decorada com @Input ()) que é vinculada ao modelo do componente.
Para responder suas perguntas:
E se eu precisar me comunicar entre os componentes irmãos?
Modelo de aplicativo compartilhado : os irmãos podem se comunicar por meio de um modelo de aplicativo compartilhado (assim como o angular 1). Por exemplo, quando um irmão faz uma alteração em um modelo, o outro irmão que tem ligações ao mesmo modelo é atualizado automaticamente.
Eventos do componente : os componentes filhos podem emitir um evento para o componente pai usando as ligações @Output (). O componente pai pode manipular o evento e manipular o modelo de aplicativo ou seu próprio modelo de visualização. As alterações no modelo de aplicativo são propagadas automaticamente para todos os componentes que se ligam direta ou indiretamente ao mesmo modelo.
Eventos de serviço : os componentes podem se inscrever em eventos de serviço. Por exemplo, dois componentes irmãos podem se inscrever no mesmo evento de serviço e responder modificando seus respectivos modelos. Mais sobre isso abaixo.
Como posso me comunicar entre um componente raiz e um componente aninhado em vários níveis?
$scope.broadcast()
do Angular 1. A próxima seção descreve essa idéia com mais detalhes.Exemplo de um serviço observável que usa eventos de serviço para propagar alterações
Aqui está um exemplo de um serviço observável que usa eventos de serviço para propagar alterações. Quando um TodoItem é adicionado, o serviço emite um evento notificando seus assinantes de componentes.
Aqui está como um componente raiz se inscreveria no evento:
Um componente filho aninhado em vários níveis se inscreveria no evento da mesma maneira:
Aqui está o componente que chama o serviço para acionar o evento (ele pode residir em qualquer lugar da árvore de componentes):
Referência: detecção de alterações em angular
fonte
itemAdded$
,. Isso é uma convenção RxJS ou algo assim? De onde vem isto?street
propriedade do modelo de aplicativo, mas como o Angular 2 implementa a detecção de alterações por identidade / referência, nenhuma alteração é propagada (onChanges
não é chamada), porque a referência do modelo de aplicativo não foi alterada ( (...)O código a seguir como exemplo de substituição de $ scope.emit () ou $ scope.broadcast () no Angular 2 usando um serviço compartilhado para manipular eventos.
Exemplo de uso:
Transmissão:
Ouvinte:
Ele pode suportar vários argumentos:
fonte
off(name, listener) { this.listeners[name] = this.listeners[name].filter(x => x != listener); }
Estou usando um serviço de mensagens que envolve um rxjs
Subject
(TypeScript)Exemplo de Plunker: Serviço de Mensagens
Os componentes podem se inscrever e transmitir eventos (remetente):
(receptor)
O
subscribe
método deMessageService
retorna umSubscription
objeto rxjs , que pode ser cancelado da seguinte maneira:Consulte também esta resposta: https://stackoverflow.com/a/36782616/1861779
Exemplo de Plunker: Serviço de Mensagens
fonte
Property 'filter' does not exist on type 'Subject<EventMessage>'.
this.handler.pipe(filter(...))
. Veja operadores locáveis .return this.handler.pipe( filter(message => message.type === type), map(message => message.payload) ).subscribe(callback);
NÃO use EventEmitter para sua comunicação de serviço.
Você deve usar um dos tipos observáveis. Eu, pessoalmente, gosto de BehaviorSubject.
Exemplo simples:
Você pode passar estado inicial, aqui eu passando nulo
Quando você deseja atualizar o assunto
Observe de qualquer serviço ou componente e aja quando receber novas atualizações.
Aqui está mais informações. .
fonte
Você pode usar o
EventEmitter ouobserváveis para criar um serviço de barramento de eventos que você registra no DI. Todo componente que deseja participar apenas solicita o serviço como parâmetro construtor e emite e / ou assina eventos.Veja também
fonte
Minha maneira favorita de fazer é usar o assunto de comportamento ou emissor de evento (quase o mesmo) em meu serviço para controlar todo o meu subcomponente.
Usando cli angular, execute ng gs para criar um novo serviço e use um BehaviorSubject ou EventEmitter
Quando você faz isso, todos os componentes que usam seu serviço como provedor estarão cientes da mudança. Simplesmente assine o resultado como você faz com eventEmitter;)
fonte
Eu criei uma amostra de pub-sub aqui:
http://www.syntaxsuccess.com/viewarticle/pub-sub-in-angular-2.0
A idéia é usar os assuntos RxJs para conectar um observador e um observável como uma solução genérica para emitir e assinar eventos personalizados. Na minha amostra, eu uso um objeto de cliente para fins de demonstração
Aqui também está uma demonstração ao vivo: http://www.syntaxsuccess.com/angular-2-samples/#/demo/pub-sub
fonte
Esta é a minha versão:
usar:
}
emitir:
fonte
Implementamos uma diretiva observável ngModelChange que envia todas as alterações de modelo por meio de um emissor de eventos que você instancia em seu próprio componente. Você simplesmente precisa vincular seu emissor de evento à diretiva.
Consulte: https://github.com/atomicbits/angular2-modelchangeobservable
No html, vincule o emissor do evento (countryChanged neste exemplo):
No seu componente de texto datilografado, faça algumas operações assíncronas no EventEmitter:
fonte
Eventos de serviço: os componentes podem se inscrever em eventos de serviço. Por exemplo, dois componentes irmãos podem se inscrever no mesmo evento de serviço e responder modificando seus respectivos modelos. Mais sobre isso abaixo.
Mas não se esqueça de cancelar a assinatura ao destruir o componente pai.
fonte