AngularJS – Acesso ao escopo filho

Se eu tenho os seguintes controladores:

function parent($scope, service) { $scope.a = 'foo'; $scope.save = function() { service.save({ a: $scope.a, b: $scope.b }); } } function child($scope) { $scope.b = 'bar'; } 

Qual é a maneira correta de deixar o parent ler b fora da child ? Se for necessário definir b em parent , isso não o tornaria semanticamente incorreto assumindo que b é uma propriedade que descreve algo relacionado a child e não a parent ?

Atualização: Pensando mais sobre isso, se mais de uma criança tivesse b , criaria um conflito para o parent no qual b deveria ser recuperado. Minha dúvida permanece: qual é a maneira correta de acessar b dos parent ?

Escopos em AngularJS usam inheritance prototypal, ao procurar uma propriedade em um escopo filho, o intérprete procurará a cadeia de protótipos a partir da criança e continuará com os pais até encontrar a propriedade, e não o contrário.

Verifique os comentários de Vojta sobre o assunto https://groups.google.com/d/msg/angular/LDNz_TQQiNE/ygYrSvdI0A0J

Em poucas palavras: você não pode acessar escopos filho de um escopo pai.

Suas soluções:

  1. Definir propriedades em pais e acessá-los de crianças (leia o link acima)
  2. Use um serviço para compartilhar o estado
  3. Passar dados por meio de events. $emit envia events para os pais até que o escopo da raiz e $broadcast despache os events para baixo. Isso pode ajudá-lo a manter as coisas semanticamente corretas.

Embora a resposta do jm-ã seja a melhor maneira de lidar com esse caso, para referência futura é possível acessar escopos filho usando os membros $ childHead, $$ childTail, $$ nextSibling e $$ prevSibling do osciloscópio. Eles não são documentados para que possam ser alterados sem aviso prévio, mas estão lá se você realmente precisar percorrer escopos.

 // get $$childHead first and then iterate that scope's $$nextSiblings for(var cs = scope.$$childHead; cs; cs = cs.$$nextSibling) { // cs is child scope } 

Violino

Você pode tentar isto:

 $scope.child = {} //declare it in parent controller (scope) 

em seguida, no controlador filho (escopo), adicione:

 var parentScope = $scope.$parent; parentScope.child = $scope; 

Agora o pai tem access ao escopo da criança.

Uma solução possível é injetar o controlador filho no controlador pai usando uma function init.

Possível implementação:

 
...
...

Onde no ChildController você tem:

 app.controller('ChildController', ['$scope', '$rootScope', function ($scope, $rootScope) { this.init = function() { $scope.parentCtrl.childCtrl = $scope.childCtrl; $scope.childCtrl.test = 'aaaa'; }; }]) 

Então agora no ParentController você pode usar:

 app.controller('ParentController', ['$scope', '$rootScope', 'service', function ($scope, $rootScope, service) { this.save = function() { service.save({ a: $scope.parentCtrl.ChildCtrl.test }); }; }]) 

Importante:
Para funcionar corretamente você tem que usar a diretiva ng-controller e renomear cada controlador usando como eu fiz no html, por exemplo.

Dicas:
Use o plug – in chrome ng-inspector durante o processo. Vai ajudar você a entender a tree.

Sim, podemos atribuir variables ​​do controlador filho às variables ​​no controlador pai. Este é um caminho possível:

Visão geral: O principal objective do código, abaixo, é atribuir $ scope.variable do controlador filho ao $ scope.assign do controlador pai.

Explicação: Existem dois controladores. No html, observe que o controlador pai inclui o controlador filho. Isso significa que o controlador pai será executado antes do controlador filho. Então, primeiro setValue () será definido e, em seguida, o controle irá para o controlador filho. $ scope.variable será atribuído como “filho”. Em seguida, esse escopo filho será passado como um argumento para a function do controlador pai, em que $ scope.assign obterá o valor como “filho”

      

this is parent: {{assign}}

this is {{variable}}

Não tenho certeza se você deve ou não “acessar” o escopo filho do pai, mas é possível. Eu sei disso porque eu mesmo fiz isso sozinho. Aqui está o meu cenário:

Eu tenho uma function que navega minhas páginas por altera a string dentro de uma variável. Essa variável é referenciada no arquivo principal index.html como um ng-include. Então, quando a string é alterada, um novo arquivo html é carregado naquela ng-include. Dentro de um desses arquivos html eu tenho outro ng-include. Pense nisso como uma janela menor na primeira janela. Toda vez que eu mudo o conteúdo dessas janelas eu também altero o conteúdo de um painel lateral. Este painel lateral está no nível pai. Mas, quando entro na janela menor dentro do pai, esse painel lateral de nível pai tem links de navegação que alteram as coisas dentro da pequena janela. Como o painel lateral está no nível pai e a navegação para a janela menor é cuidada em seu próprio controlador no nível filho, quando clico nos links no painel lateral, ele precisa editar o controlador filho. Isso pode ser uma má programação. Honestamente, eu não sei. Eu comecei com angularjs há alguns meses e ainda estou aprendendo. Mas, para que funcione no meu cenário, criei uma function no escopo pai, que é chamada quando o escopo filho é carregado:

 function parent($scope, service) { setCurrentChildController = function (childScope) { this.$scope.childScope = childScope; } } function child($scope) { scope.$parent.setCurrentChildController($scope); } 

Portanto, agora a variável $ scope.childScope do escopo pai é essencialmente o escopo do controlador filho. Tem access a todas as variables ​​e funções dentro do escopo filho. Se isso é uma má programação e qualquer um pode encontrar uma solução alternativa para o problema com o meu cenário que seria ótimo. Mas isso funciona se necessário.