Frage Angular-Direktive: Verwenden von ng-Modell innerhalb des Isolationsbereichs


Ich habe Probleme, herauszufinden, wie ich eine benutzerdefinierte Anweisung definieren kann, die beide:

  1. Verwendet den Gültigkeitsbereich isolieren und
  2. Verwendet die ng-model-Direktive in einem neuen Bereich innerhalb ihrer Vorlage.

Hier ist 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 gewünschte Verhalten ist hier, dass der Wert der Eingabe an den äußeren Umfang gebunden ist foo.bar Eigentum, über den Anwendungsbereich 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, also der Bereich dieses Bereichs model das wird aktualisiert, nicht der Anwendungsbereich der Richtlinie. Normalerweise lösen Sie diese ng-Modellprobleme, indem Sie sicherstellen, dass ein Punkt im Ausdruck vorhanden ist, aber ich sehe keinen Weg, dies hier zu tun. Ich fragte mich, ob ich vielleicht so etwas für meine Anweisung verwenden könnte:

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

aber das funktioniert nicht ...

Plunker


10
2018-06-17 14:00


Ursprung


Antworten:


Sie haben Recht - ng - wenn Sie einen untergeordneten Bereich erstellen, der ein Problem verursacht, wenn Text in das Eingabetextfeld eingegeben wird. Sie 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 Zwei-Wege-Modellbindung effektiv aufgehoben.

Die Lösung dafür ist einfach. Geben Sie in Ihrer Vorlage das $ -Parent-Präfix an:

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

Dadurch wird sichergestellt, dass "Modell" aus dem übergeordneten Bereich "$" aufgelöst wird, den Sie bereits für die bidirektionale Modellbindung über den isolierten Bereich eingerichtet haben.

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ützt {{model}} bindende Ausdrücke).


9
2018-06-17 14:28



ng-if Erstellt einen zusätzlichen prototypischen Erbenbereich, also ng-model="model" bindet an die vererbte Eigenschaft des neuen Bereichs und nicht an die Eigenschaft 2-way binded des Anweisungsbereichs.

Ändern Sie es in ng-show und es wird Arbeit.

Sie können verwenden eine kleine Firebug-Erweiterung Ich habe geschrieben, um Winkelbereiche zu inspizieren.


0
2018-06-17 14:21