2013-06-06 5 views
47

Wie kann ich Variablenänderungen übernehmen und problemlos an die ParentCtrl weitergeben, obwohl eine neue Variable in ChildCtrl instanziiert wird? Extra-Punkte für minimale bis keine $ auf der und $ Armbanduhr (macht es einfacher zu implementieren)Angular JS propagieren die Änderung der untergeordneten Bereichsvariablen in den übergeordneten Bereich

ParentCtrl

  • ChildCtrl/ChildCtrl2/ChildCtrl3/ChildCtrl4

    • Ansicht

Meine ChildCtrls sind einfach anders genug, wo ich nicht einfach abstrahieren kann Aster Layout und eine ng-Ansicht, aber alle hängen von den gleichen Funktionen in ParentCtrl ab.

$ scope.searchTerms ist in ParentCtrl definiert, aber das Eingabefeld mit ng-model = 'searchTerms' befindet sich in der Ansicht der untergeordneten Controller. Wenn diese Variable geändert wird, werden in der ParentCtrl nicht nur die ChildCtrls angezeigt.

Beispiel: http://jsfiddle.net/JHwxP/22/

HTML Teil

<div ng-app> 
    <div ng-controller="Parent"> 
     parentX = {{x}} <br/> 
     parentY = {{y}}<br/> 
     <div ng-controller="Child"> 
      childX = {{x}}<br/> 
      childY = {{y}}<br/> 
      <a ng-click="modifyBothScopes()">modifyBothScopes</a><br> 
      <br> 
      The changes here need to appear in 'Parent'. <input ng-model='y'> 
     </div> 
    </div> 
</div> 

Controller

function Parent($scope) { 
    $scope.x= 5; 
    $scope.y= 5; 
} 

function Child($scope) { 
    $scope.modifyBothScopes= function() { 
     $scope.$parent.x++; 
    }; 
} 

UPDATE

Ich bin derzeit ein Shared-Service-Ansatz versucht: https://gist.github.com/exclsr/3595424

UPDATE

Versuch, ein emit/Broadcast-System

Problem gelöst: Ich war $ scope.searchTerms in der Mutter Speicherung und wenn geändert, um einen Raum in dem Kind $ Bereich erstellt.

Lösung: Ich sollte $ scope.search.terms im Elternteil getan haben und wenn es im Kind geändert wurde, würde es zum Elternteil aufblasen.

Beispiel: http://jsfiddle.net/JHwxP/23/

Antwort

87

Dies ist darauf zurückzuführen, wie prototypische Vererbung funktioniert.

Wenn Sie im untergeordneten Controller nach $scope.x fragen, wird überprüft, ob x in seinem Bereich definiert ist. Ist dies nicht der Fall, wird im übergeordneten Bereich nach x gesucht.

Wenn Sie der Eigenschaft x des untergeordneten Bereichs zuweisen, wird nur der untergeordnete Bereich geändert.

Eine einfache Möglichkeit, dies zu umgehen und das Freigabeverhalten zu erhalten, besteht darin, ein Objekt oder ein Array zu verwenden.

function ParentCtrl($scope) { 
    $scope.model = {x: 5, y: 5}; 
} 

function ChildCtrl($scope) { 
    $scope.update = function(x, y) { 
    $scope.model.x = x; 
    $scope.model.y = y; 
    }; 
} 

Hier werden die Änderungen in den beiden Bereichen sichtbar sein, weil $scope.model auf das gleiche Objekt in beiden Eltern und Kind-Bereiche beziehen.

John Lindquist hat eine video on this.

+9

Ich wusste von Miskos "Wenn du keinen Punkt benutzt, machst du etwas falsch." rede aber ich hatte noch nie erfahren warum. Hier ist ein funktionierendes Beispiel für Ihre Antwort: http://jsfiddle.net/JHwxP/23/ –

+0

Ok, jetzt kann ich tote Leute sehen !!!!! Danke –

13

Eine andere Lösung, die nicht das Erstellen eines Bündels von Objekten für die Referenzverknüpfung umfasst, ist das Erstellen von Setter-Funktionen im übergeordneten Controller.

Ich finde dies sauberer, wenn es nicht sinnvoll ist, die Daten Teil des gleichen Objekts zu haben.

könnten Sie auch verrückt werden und in dem Kind so etwas tun:

function ChildCtrl($scope) { 
    var superSetX = $scope.setX; 
    $scope.setX = function(value) { 
    superSetX(value * 2); 
    }; 
    ... 
} 
0

ich für so etwas suchte. Die erste Lösung kam nach dem Lesen this. Sie können ein übergeordnetes Modell für einen untergeordneten Controller freigeben.

Here is an example. Ich benutze sogar eine Reihe von Gegenständen, um meinen Standpunkt zu beweisen. Die ChildController ist ändern seine Eltern, als wären sie alle Teil des gleichen Universums.

Verwandte Themen