2013-01-09 10 views
6

In einem übergeordneten Controller-Bereich habe ich selectedItem definiert, die auf 'x' festgelegt ist. Dann in dem Kind Umfang habe ich selectedItem mit ngModel definiert:Vererbung für Bereiche in AngularJS

<div ng-app> 
    <div ng-controller="CtrlA"> 
     <div ng-controller="CtrlB"> 
     <select ng-model="selectedItem" ng-options="item for item in items"> 
     </select> 
     </div> 
    </div> 
</div> 

function CtrlA($scope) { 
    $scope.selectedItem = 'x'; 
    $scope.items = ['x', 'y']; 
} 

function CtrlB($scope) {} 

Wenn die Seite geladen wird, wird die selectedItem richtig auf ‚x‘, wie erwartet. Wenn ich 'y' wähle, gibt in CtrlB $ scope 'y' wie erwartet aus.

Aber wenn ich $scope.selectedItem in CtrlA Geltungsbereich (mit AngularJS Batarang) untersuchen, gibt es "x".

jsFiddle: http://jsfiddle.net/sudhh/GGKjp/2/

Vorschauseite: http://fiddle.jshell.net/sudhh/GGKjp/2/show/light/ (für mit AngularJS batarang Inspektion)

Warum ist $scope.selectedItem in CtrlA Umfang nicht auf 'y' aktualisiert zu werden? Was ist die Erklärung?

Ich bevorzuge keine Ereignisse zu verwenden oder zu aktualisieren selectedItem im übergeordneten Bereich (für Lernzwecke).

+1

Seien Sie sicher, mit Stapelüberlauf Frage * http zu lesen: //stackoverflow.com/questions/14049480 * Es gibt einen guten Überblick über die Vererbung von Bereichen in AngularJS. – Martijn

Antwort

7

Wenn Sie versuchen, auf einem primitiven auf geordneten Bereich erklärt zu binden, dann ist die selectedItem in Kind Umfang wirksam in das Eigentum des gleichen Namen im übergeordneten Bereich Schatten wird. für Ihr Modell

In diesem Fall gibt es 3 Möglichkeiten

  1. Objekte im übergeordneten definieren, dann verweisen auf eine Eigenschaft des Objekts in dem Kind: ref.selectedItem
  2. Verwendung $ parent.selectedItem (nicht immer möglich, aber einfacher als 1. wo möglich)
  3. eine Funktion auf dem übergeordneten Bereich definieren, und es von dem Kind nennen, an die Mutter den Grundwert vorbei (nicht immer möglich)

Mehr darüber auf https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance

können Sie die aktualisierte Geige finden den ersten Ansatz bei http://jsfiddle.net/sudhh/XU2rP/1/

function CtrlA($scope) { 
    $scope.items = ['x', 'y']; 
    $scope.ref = { 
    selectedItem: 'x' 
    }; 
} 
+0

In der Tat habe ich Ihren Code in diesem [jsFiddle] etwas erweitert (http://jsfiddle.net/asgoth/fDhcr/) indem man Uhren benutzt, die zur Konsole loggen. Nur die Uhr in B wird ausgelöst. – asgoth

0

Ich habe in ähnlichen Fällen bemerkt, dass AngularJSselectedItem nicht richtig zu sehen ist. Der einzige Weg, den ich gefunden habe, ist, mit einem Eintrag aus dem Array items zu initialisieren. Versuchen Sie Folgendes:

function CtrlA($scope) { 
    $scope.items = ['x', 'y']; 
    $scope.selectedItem = $scope.items[0]; 
} 
+0

Funktioniert immer noch nicht. Wenn Sie im Dropdown-Menü "y" auswählen und den Bereich prüfen, gibt CtrlB "y" wie erwartet aus, aber CtrlA zeigt weiterhin ausgewähltes Element als "x" an. – sudhakar

+1

Angular beobachtet 'selectedItem' richtig. Das Problem besteht darin, dass es zwei 'selectedItem'-Eigenschaften gibt - eine im übergeordneten Bereich und eine im untergeordneten Bereich. Angular beobachtet beide, richtig, aber unabhängig. Aufgrund der Art und Weise, wie die JavaScript-Prototyp-Vererbung funktioniert, wird der untergeordnete Bereich nur seine Eigenschaft und der übergeordnete Bereich nur seine Eigenschaft sehen.Sie möchten, dass der untergeordnete Bereich die Eigenschaft verwendet, die bereits im übergeordneten Bereich vorhanden ist, und keine neue Eigenschaft erstellen. (Ich habe gesehen, dass @sudhakar bereits die Antwort gefunden hat, ich wollte nur klarstellen, was vor sich geht.) –