Eu tenho dois controladores angulares:
function Ctrl1($scope) {
$scope.prop1 = "First";
}
function Ctrl2($scope) {
$scope.prop2 = "Second";
$scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}
Não posso usar por Ctrl1
dentro Ctrl2
porque é indefinido. No entanto, se eu tentar passar assim ...
function Ctrl2($scope, Ctrl1) {
$scope.prop2 = "Second";
$scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}
Eu recebo um erro. Alguém sabe como fazer isso?
Fazendo
Ctrl2.prototype = new Ctrl1();
Também falha.
NOTA: Esses controladores não estão aninhados um no outro.
javascript
angularjs
angularjs-controller
dopatraman
fonte
fonte
Respostas:
Uma maneira de compartilhar variáveis entre vários controladores é criar um serviço e injetá-lo em qualquer controlador em que você deseja usá-lo.
Exemplo simples de serviço:
Usando o serviço em um controlador:
Isso é descrito muito bem neste blog (lição 2 e em particular).
Descobri que se você deseja vincular a essas propriedades em vários controladores, funcionará melhor se você vincular à propriedade de um objeto em vez de um tipo primitivo (booleano, string, número) para manter a referência vinculada.
Exemplo: em
var property = { Property1: 'First' };
vez devar property = 'First';
.ATUALIZAÇÃO: Para (espero) tornar as coisas mais claras, aqui está um violino que mostra um exemplo de:
fonte
both
para ser uma função e ela será chamada / reavaliada durante o processo de resumo angular. Veja este violino para um exemplo. Além disso, se você vincular à propriedade de um objeto, poderá usá-lo diretamente em sua visualização e ele será atualizado conforme os dados forem alterados de maneira semelhante a este exemplo .getProperty()
função ao escopo e usar $ scope. $ Watch como neste exemplo . Espero que esses exemplos ajudem!.service
não.factory
como descrito nos documentos angulares. Por que essa resposta é votada tão alto quando a documentação usa um método diferente?Eu gosto de ilustrar coisas simples com exemplos simples :)
Aqui está um
Service
exemplo muito simples :E aqui o jsbin
E aqui está um
Factory
exemplo muito simples :E aqui o jsbin
Se isso é muito simples, aqui está um exemplo mais sofisticado
Consulte também a resposta aqui para comentários relacionados a práticas recomendadas
fonte
var _dataObj = {};
quando você retorna uma referência direta a ele ..? Isso não é particular . No primeiro exemplo você pode fazerthis.dataObj = {};
e no segundoreturn { dataObj: {} };
é uma declaração de variável inútil IMHO.--- Eu sei que esta resposta não é para esta pergunta, mas quero que as pessoas que leem essa pergunta e queiram lidar com serviços como fábricas evitem problemas ao fazer isso ----
Para isso, você precisará usar um Serviço ou uma Fábrica.
Os serviços são a MELHOR PRÁTICA para compartilhar dados entre controladores não aninhados.
Uma anotação muito boa sobre esse tópico sobre compartilhamento de dados é como declarar objetos. Tive azar porque caí em uma armadilha do AngularJS antes de ler sobre isso e fiquei muito frustrado. Então, deixe-me ajudá-lo a evitar esse problema.
Eu li no "ng-book: O livro completo sobre o AngularJS" que os modelos ng do AngularJS criados nos controladores como dados nus estão ERRADOS!
Um elemento $ scope deve ser criado assim:
E não é assim:
Isso ocorre porque é recomendado (BEST PRACTICE) para o DOM (documento html) conter as chamadas como
Isso é muito útil para controladores aninhados se você desejar que seu controlador filho possa alterar um objeto do controlador pai ....
Porém, no seu caso, você não deseja escopos aninhados, mas há um aspecto semelhante para obter objetos dos serviços para os controladores.
Digamos que você tenha o seu serviço 'Factory' e, no espaço de retorno, existe um objetoA que contém o objetoB que contém o objetoC.
Se do seu controlador você deseja colocar o objetoC no seu escopo, é um erro dizer:
Isso não vai funcionar ... Em vez disso, use apenas um ponto.
Em seguida, no DOM, você pode chamar objectC a partir de objectA. Essa é uma prática recomendada relacionada às fábricas e, o mais importante, ajudará a evitar erros inesperados e não alcançáveis.
fonte
Solução sem criar Serviço, usando $ rootScope:
Para compartilhar propriedades entre os Controladores de aplicativos, você pode usar Angular $ rootScope. Essa é outra opção para compartilhar dados, colocando-os para que as pessoas saibam sobre eles.
A maneira preferida de compartilhar alguma funcionalidade entre os Controladores é Serviços, para ler ou alterar uma propriedade global, você pode usar $ rootscope.
Usando $ rootScope em um modelo (acesse as propriedades com $ root):
fonte
A amostra acima funcionou como um encanto. Fiz uma modificação apenas no caso de precisar gerenciar vários valores. Eu espero que isso ajude!
fonte
.factory
. Um.service
deve ser utilizado "se você definir o seu serviço como um tipo / classe" como por docs.angularjs.org/api/auto/service/$provide#serviceEu costumo usar valores, feliz por qualquer um discutir por que essa é uma má idéia.
Injete o valor de acordo com um serviço.
Definido em ctrl1:
e acesso a partir de ctrl2:
fonte
O exemplo a seguir mostra como passar variáveis entre controladores irmãos e executar uma ação quando o valor for alterado.
Exemplo de caso de uso: você tem um filtro em uma barra lateral que altera o conteúdo de outra visualização.
fonte
Eu gostaria de contribuir para essa pergunta, salientando que a maneira recomendada de compartilhar dados entre controladores e até diretivas é usando serviços (fábricas), como já foi apontado, mas também gostaria de fornecer um exemplo prático de como fazer isso.
Aqui está o plunker de trabalho: http://plnkr.co/edit/Q1VdKJP2tpvqqJL1LF6m?p=info
Primeiro, crie seu serviço , que terá seus dados compartilhados :
Em seguida, basta injetar nos controladores e pegar os dados compartilhados no seu escopo:
Você também pode fazer isso pelas suas diretivas , da mesma maneira:
Espero que esta resposta prática e limpa possa ser útil para alguém.
fonte
Você poderia fazer isso com serviços ou fábricas. Eles são essencialmente os mesmos para algumas diferenças principais. Eu achei essa explicação no thinkster.io a mais fácil de seguir. Simples, direto ao ponto e eficaz.
fonte
Você também não poderia tornar a propriedade parte do pai dos escopos?
Não estou dizendo que está certo, mas funciona.
fonte
NOTE: These controllers are not nested inside each other.
. Se fossem controladores aninhados ou compartilhados com o mesmo pai, isso funcionaria, mas não podemos esperar isso.$parent
se isso puder ser evitado. Um componente reutilizável bem projetado não deve saber sobre seus pais.Ah, tenha um pouco desse material novo como outra alternativa. É o armazenamento local e funciona onde o angular funciona. De nada. (Mas sério, obrigado o cara)
https://github.com/gsklee/ngStorage
Defina seus padrões:
Acesse os valores:
Armazene os valores
Lembre-se de injetar ngStorage no seu aplicativo e $ localStorage no seu controlador.
fonte
Existem duas maneiras de fazer isso
1) Use o serviço de obtenção / configuração
2)
$scope.$emit('key', {data: value}); //to set the value
fonte
Segunda Abordagem:
Html:
Para mais detalhes, consulte plunker:
http://plnkr.co/edit/cKVsPcfs1A1Wwlud2jtO?p=preview
fonte
Ctrl2
(o ouvinte) for um controlador filho deCtrl1
. Os controladores irmãos precisam se comunicar via$rootScope
.Se você não deseja prestar serviços de manutenção, pode fazer assim.
fonte
Além de $ rootScope e serviços, há uma solução alternativa limpa e fácil de estender angular para adicionar os dados compartilhados:
nos controladores:
Essas propriedades pertencem ao objeto 'angular', separado dos escopos, e podem ser compartilhadas em escopos e serviços.
Um benefício é que você não precisa injetar o objeto: eles são acessíveis em qualquer lugar imediatamente após a sua definição!
fonte
window
objeto ... Se você estiver indo para poluir angular, porque não basta ir em frente e poluem o objeto de janela ...