2014-06-17 4 views
10

Ich habe Probleme, herauszufinden, wie ich eine benutzerdefinierte Richtlinie definieren, die beide:Angular Richtlinie: Verwendung von ng-Modell innerhalb Isolat Umfangs

  1. Uses Umfang zu isolieren und
  2. Verwendet die ng-Modell Richtlinie in einem neuen Bereich innerhalb seiner Vorlage.

Hier ein Beispiel:

HTML:

<body ng-app="app"> 
    <div ng-controller="ctrl"> 
    <dir model="foo.bar"></dir> 
    Outside directive: {{foo.bar}} 
    </div> 
</body> 

JS:

var app = angular.module('app',[]) 
    .controller('ctrl', function($scope){ 
    $scope.foo = { bar: 'baz' }; 
    }) 
    .directive('dir', function(){ 
    return { 
     restrict: 'E', 
     scope: { 
     model: '=' 
     }, 
     template: '<div ng-if="true"><input type="text" ng-model="model" /><br/></div>' 
    } 
    }); 

Das hier gewünschte Verhalten ist, dass der Wert der auf den äußeren Umfang des gebunden ist foo.bar Eigenschaft, über den Geltungsbereich der Richtlinie (isolieren) model Eigentum. Das passiert nicht, weil die ng-if-Anweisung für das umschließende div der Vorlage einen neuen Bereich erstellt. Daher wird der Bereich model des Bereichs aktualisiert, nicht der Bereich der Richtlinie. Normalerweise lösen Sie diese ng-Modell Probleme, indem Sie sicherstellen, dass ein Punkt im Ausdruck ist, aber ich sehe keine Möglichkeit, dies hier zu tun. Ich fragte mich, ob ich so etwas wie dies könnte in der Lage sein, für meine Richtlinie zu verwenden:

{ 
    restrict: 'E', 
    scope: { 
    model: { 
     value: '=model' 
    } 
    }, 
    template: '<div ng-if="true"><input type="text" ng-model="model.value" /><br/></div>' 
} 

aber das nicht funktioniert ...

Plunker

Antwort

9

Sie haben Recht - ng-wenn erstellt einen untergeordneten Bereich, der ein Problem verursacht, wenn Text in das Eingabetextfeld eingegeben wird. Es erstellt eine Schatteneigenschaft mit dem Namen "model" im untergeordneten Bereich, bei der es sich um eine Kopie der übergeordneten Bereichsvariable mit demselben Namen handelt. Dadurch wird die Zweiwegemodellbindung effektiv aufgehoben.

Die Lösung dafür ist einfach. In der Vorlage, geben Sie den Präfix $ parent:

template: '<div ng-if="true"> 
        <input type="text" ng-model="$parent.model" /><br/> 
      </div>' 

Dies stellt sicher, dass es ‚Modell‘ lösen wird aus dem $ geordneten Bereich, die Sie bereits eingerichtet haben für Zwei-Wege-Modell durch den isolierten Umfang verbindlich.

Am Ende ist das '.' In ng-Modell spart den Tag. Ich finde es nützlich, über alles nachzudenken, was von dem Punkt übrig bleibt, als eine Möglichkeit für Angular, die Eigenschaft durch Vererbung des Gültigkeitsbereichs aufzulösen. Ohne den Punkt wird das Auflösen der Eigenschaft nur dann zu einem Problem, wenn wir Bereichsvariablen zuweisen (andernfalls sind Suchvorgänge in Ordnung, einschließlich schreibgeschützter {{model}} Bindungsausdrücke).

+1

Danke - Ich hatte total über $ Eltern vergessen.Dies löst mein Problem in diesem Fall, aber ich bin immer noch ein bisschen zögerlich als Allzwecklösung: Es bedeutet, dass ich nachverfolgen muss, wo neue Bereiche in meinen Vorlagen eingeführt werden und welche Ebene der Hierarchie ich brauche Ziel, das ziemlich fehleranfällig scheint ... – Duncan

+0

Ich stimme dir zu. Misko erklärte, dass jemand etwa einmal in der Woche einen Fehler meldet - es ist nicht wirklich ein Fehler, so wie die prototypische Vererbung funktioniert. Um das ng-Modell korrekt zu setzen, müssen Sie wissen, wie die Vererbung von Bereichen auf einer tieferen Ebene funktioniert und welche Direktiven untergeordnete Bereiche erstellen. Ich kann mir keinen besseren Weg vorstellen. – pixelbits

+0

Ja, guter Punkt, obwohl ich denke, was ich bekam, ist, dass es ein besonderes Problem gibt mit ng-model = "$ parent.bar" im Gegensatz zu ng-model = "foo.bar", in dem mit dem ersteren Ich muss immer darüber nachdenken, wo Childscopes erstellt werden, während ich bei letzteren nicht (solange ich davon ausgehen kann, dass keine Childscopes eine Eigenschaft namens "foo" haben). – Duncan

0

ng-if schafft einen zusätzlichen prototypally Umfang vererben, so ng-model="model" bindet an die vererbte Eigenschaft des neuen Bereichs und nicht an die Eigenschaft 2-way binded des Anweisungsbereichs.

Ändern Sie es zu ng-show und es wird work.

Sie können a small Firebug extension verwenden, die ich geschrieben habe, um Winkelbereiche zu inspizieren.

+0

Ja, ich verstehe, dass das ist, was passiert - ich habe ng-wenn absichtlich, nur um das Problem zu zeigen – Duncan

Verwandte Themen