É possível ter um controlador usando outro?
Por exemplo:
Este documento HTML simplesmente imprime uma mensagem entregue pelo MessageCtrl
controlador no messageCtrl.js
arquivo.
<html xmlns:ng="http://angularjs.org/">
<head>
<meta charset="utf-8" />
<title>Inter Controller Communication</title>
</head>
<body>
<div ng:controller="MessageCtrl">
<p>{{message}}</p>
</div>
<!-- Angular Scripts -->
<script src="http://code.angularjs.org/angular-0.9.19.js" ng:autobind></script>
<script src="js/messageCtrl.js" type="text/javascript"></script>
</body>
</html>
O arquivo do controlador contém o seguinte código:
function MessageCtrl()
{
this.message = function() {
return "The current date is: " + new Date().toString();
};
}
O que simplesmente imprime a data atual;
Se eu adicionasse outro controlador, DateCtrl
que devolvesse a data em um formato específico MessageCtrl
, como alguém faria isso? A estrutura de DI parece estar preocupada XmlHttpRequests
e acessando serviços.
javascript
html
angularjs
BanksySan
fonte
fonte
Respostas:
Existem várias maneiras de se comunicar entre controladores.
O melhor é provavelmente compartilhar um serviço:
Outra maneira é emitir um evento no escopo:
Nos dois casos, você também pode se comunicar com qualquer diretiva.
fonte
Veja este violino: http://jsfiddle.net/simpulton/XqDxG/
Assista também ao vídeo a seguir: Comunicação entre controladores
Html:
javascript:
fonte
Se você deseja chamar um controlador para outro, existem quatro métodos disponíveis
O controlador e seu escopo podem ser destruídos, mas o $ rootScope permanece no aplicativo, é por isso que estamos usando o $ rootScope porque $ rootScope é o pai de todos os escopos.
Se você estiver realizando a comunicação de pai para filho e até o filho quiser se comunicar com seus irmãos, poderá usar $ broadcast
Se você estiver executando uma comunicação de filho para pai, sem irmãos envolvidos, você poderá usar $ rootScope. $ Emit
HTML
Código Angularjs
No console de código acima, $ emit 'childEmit' não chamará dentro de irmãos filhos e chamará somente dentro de pai, onde $ broadcast também é chamado dentro de irmãos e pai.Este é o lugar onde o desempenho entra em ação. preferível, se você estiver usando a comunicação filho-pai, porque ignora algumas verificações sujas.
É um dos melhores métodos. Se você deseja fazer a comunicação entre pais e filhos, onde os filhos desejam se comunicar com os pais imediatos , não seria necessário nenhum tipo de transmissão ou emissão de $, mas se você deseja fazer comunicação entre pais e filhos, precisará use service ou $ broadcast
Por exemplo HTML: -
Angularjs
Sempre que você estiver usando a comunicação filho-pai, o Angularjs procurará uma variável dentro do filho. Se não estiver presente no interior, escolherá ver os valores no controlador pai.
O AngularJS suporta os conceitos de "Separação de preocupações" usando a arquitetura de serviços. Os serviços são funções javascript e são responsáveis por executar apenas tarefas específicas. Isso os torna uma entidade individual que pode ser mantida e testada . Serviços usados para injetar usando o mecanismo de injeção de dependência do Angularjs.
Código Angularjs:
Ele fornecerá a saída Hello Child World e Hello Parent World. De acordo com os documentos angulares dos serviços Singletons - Cada componente dependente de um serviço obtém uma referência à instância única gerada pela fábrica de serviços .
Esse método obtém o scope () do elemento por seu método Id / exclusivo class.angular.element () retorna o elemento e o scope () fornece a variável $ scope de outra variável usando a variável $ scope de um controlador dentro de outro não é uma boa prática.
HTML: -
Angularjs: -
No código acima, os controladores estão mostrando seu próprio valor em HTML e, quando você clica no texto, obtém valores no console de acordo. Se você clicar no período dos controladores pai, o navegador consola o valor de child e vice-versa.
fonte
Aqui está um exemplo de uma página de dois controladores que compartilham dados de serviço:
Também aqui: https://gist.github.com/3595424
fonte
theService
as atualizaçõesthing.x
, em seguida, que a mudança propageates automaticamente para o <input> S emFirstCtrl
eSecondCtrl
, certo? E também é possível mudarthing.x
diretamente através de qualquer um dos dois <input> s (certo?).Se você deseja emitir e transmitir eventos para compartilhar dados ou chamar funções entre controladores , consulte este link : e verifique a resposta em
zbynour
(responda com o máximo de votos). Estou citando sua resposta !!!Se o escopo do firstCtrl for o pai do escopo do secondCtrl, seu código funcionará substituindo $ emit por $ broadcast no firstCtrl:
Caso não exista relação pai-filho entre seus escopos, você pode injetar $ rootScope no controlador e transmitir o evento para todos os escopos filhos (por exemplo, também secondCtrl).
Finalmente, quando você precisar despachar o evento do controlador filho para escopos para cima, poderá usar $ scope. $ Emit. Se o escopo de firstCtrl for o pai do escopo secondCtrl:
fonte
Mais dois problemas: (Abordagem sem serviço)
1) Para controlador
$scope
pai- filho - Uso do controlador pai para emitir / transmitir eventos. http://jsfiddle.net/laan_sachin/jnj6y/2) Utilização
$rootScope
em controladores não relacionados. http://jsfiddle.net/VxafF/fonte
Na verdade, o uso de emissão e transmissão é ineficiente porque o evento borbulha para cima e para baixo na hierarquia do escopo, o que pode facilmente se degradar em agrupamento de desempenho para um aplicativo complexo.
Eu sugeriria usar um serviço. Aqui está como eu o implementei recentemente em um dos meus projetos - https://gist.github.com/3384419 .
Ideia básica - registre um barramento de sub-evento / pub como um serviço. Em seguida, injete esse barramento de eventos sempre que precisar para assinar ou publicar eventos / tópicos.
fonte
Eu também sei desse jeito.
Mas não uso muito, porque não gosto de usar seletores jQuery no código angular.
fonte
Existe um método não dependente de serviços
$broadcast
ou$emit
. Não é adequado em todos os casos, mas se você tiver 2 controladores relacionados que podem ser abstraídos em diretivas, poderá usar arequire
opção na definição de diretiva. É mais provável como o ngModel e o ngForm se comunicam. Você pode usar isso para se comunicar entre controladores de diretiva que estão aninhados ou no mesmo elemento.Para uma situação de pai / filho, o uso seria o seguinte:
E os principais pontos para fazê-lo funcionar: Na diretiva pai, com os métodos a serem chamados, você deve defini-los em
this
(não em$scope
):Na definição de diretiva filho, você pode usar a
require
opção para que o controlador pai seja passado para a função de link (para que você possa chamar funções nele a partirscope
da diretiva filho.O acima pode ser visto em http://plnkr.co/edit/poeq460VmQER8Gl9w8Oz?p=preview
Uma diretiva irmão é usada da mesma forma, mas ambas as diretivas no mesmo elemento:
Usado criando um método em
directive1
:E na diretiva2, isso pode ser chamado usando a
require
opção que resulta na passagem do siblingController para a função de link:Isso pode ser visto em http://plnkr.co/edit/MUD2snf9zvadfnDXq85w?p=preview .
Os usos disso?
Pai: qualquer caso em que os elementos filhos precisem "se registrar" com um pai. Muito parecido com o relacionamento entre ngModel e ngForm. Isso pode adicionar um certo comportamento que pode afetar os modelos. Você também pode ter algo puramente baseado em DOM, em que um elemento pai precisa gerenciar as posições de determinados filhos, por exemplo, gerenciar ou reagir à rolagem.
Irmão: permite que uma diretiva tenha seu comportamento modificado. O ngModel é o caso clássico, para adicionar analisadores / validação ao uso do ngModel nas entradas.
fonte
Não sei se isso está fora dos padrões, mas se você tiver todos os seus controladores no mesmo arquivo, poderá fazer algo assim:
Como você pode ver indicadores, o Ctrl está chamando as funções updateChart dos outros dois controladores ao chamar updateCharts.
fonte
Você pode injetar o serviço '$ controller' no controlador pai (MessageCtrl) e instanciar / injetar o controlador filho (DateCtrl) usando:
$scope.childController = $controller('childController', { $scope: $scope.$new() });
Agora você pode acessar os dados do seu controlador filho chamando seus métodos, pois é um serviço.
Deixe-me saber se houver algum problema.
fonte
A seguir, é apresentada uma
publish-subscribe
abordagem independente do JS angular.Controlador de parâmetros de pesquisa
Controlador de opções de pesquisa
Gerente de eventos
Global
fonte
No angular 1.5, isso pode ser feito da seguinte maneira:
Este é o componente pai. Nisto, criei uma função que empurra outro objeto para a minha
productForms
matriz - note - este é apenas o meu exemplo, essa função pode ser algo realmente.Agora podemos criar outro componente que fará uso de
require
:Aqui, o componente filho está criando uma referência à função do componente pai,
addNewForm
que pode ser vinculada ao HTML e chamada como qualquer outra função.fonte