2012-12-12 15 views
16

Ich denke, ich vermisse etwas einfach (und wichtig) hier. Ich verwende eine Vorlage enthalten, die eine Eingabe enthält, die auf einen Wert abgebildet ist:Angularjs: 2-Wege-Bindung funktioniert nicht in der mitgelieferten Vorlage

<div ng-controller="Ctrl"> 
    <div ng-include src="'template.html'"></div> 
</div> 

<!-- template --> 
<script type="text/ng-template" id="template.html"> 
    <input ng-model="testvalue" /> 
</script> 

Controller:

function Ctrl($scope) {  
    $scope.testvalue= "initial value"; 
}​ 

den Wert von $ scope.testvalue immer Alerting zeigt den Ausgangswert, nicht der aktualisierten Wert (wenn Sie die Eingabe eingeben). Hilf mir Obi-Wan. Du bist unsere einzige Hoffnung.

Fiddle: http://jsfiddle.net/h5aac/

Antwort

31

Dies ist nur allzu häufig zu einer primitiven anstelle eines Objekts zu binden. Der Wert der Zeichenfolge wird umgangen und nicht eine Referenz auf ein Objekt. Wenn Sie ein Objekt anstelle eines Grundelements verwenden, funktioniert es einwandfrei. So etwas in deinem Umfang.

$scope.foo = {testvalue: "initial value"}; 

Siehe http://jsfiddle.net/h5aac/2/

auch:

Using `ng-model` within a transcluded directive in AngularJS

binding issue when a directive in a ngRepeat

AngularJS - updating scope value with asynchronous response

Ich bin sicher, dass es mehr gibt ...

+0

Danke, das war es genau. Ist das ein "Bug" in eckigen, oder ist dies beabsichtigt/erwartet? – Caleb

+4

Ich würde es nicht wirklich einen "Bug" nennen. Es ist nur eine Frage der Funktionsweise von Javascript-Objekten und -Primitiven, wenn sie herumgereicht werden. Wenn Sie eine Variable, die auf eine Zeichenfolge festgelegt ist und Sie es in eine Funktion übergeben, kann die Funktion alles ändern, was es will, und es wird nicht den Wert der ursprünglichen Var beeinflussen. Wenn diese Variable auf ein Objekt festgelegt wurde, wird eine Referenz übergeben, und alle Änderungen in der Funktion wirken sich auf das Objekt aus, auf das die ursprüngliche Variable verwiesen hat. Hoffe, das macht Sinn. – dnc253

+0

Ja, das macht Sinn. Vielen Dank! – Caleb

7

Eine Alternative eine Objekteigenschaft im übergeordneten Bereich zu referenzieren ist $ parent zu verwenden, um die primitiven im übergeordneten Bereich zuzugreifen:

<input ng-model="$parent.testvalue" /> 

ng-umfassen erstellt ein Kind Umfang. Dieser Bereich erbt prototypisch den übergeordneten Bereich von Ctrl. Hier ist, wie die 3 Varianten arbeiten:

  • $ parent.testvalue bindet das Modell auf die Eigenschaft im übergeordneten Bereich
  • Testvalue selbst bindet das Modell auf eine neue Eigenschaft, die auf das Kind Bereich erstellt werden. Diese Eigenschaft "schattiert/verbirgt" die Eigenschaft des übergeordneten Bereichs mit demselben Namen.
  • foo.testvalue (z. B. siehe @dnc253's Antwort) bindet das Modell auch an eine Elterneigenschaft. Es funktioniert wie folgt: Javascript sieht/findet 'foo' im Kindbereich nicht, also sucht es im Elternbereich (wegen der prototypischen Vererbung) und findet es dort.

Um zu sehen, was das Kind Umfang aussieht, verwenden Sie das Original-Geige, und fügen Sie diesen Code in Ihre Vorlage irgendwo:

<a ng-click="showScope($event)">show scope</a> 

Und diesen Code auf Ihre Ctrl hinzufügen:

$scope.showScope = function(e) { 
    console.log(angular.element(e.srcElement).scope()); 
} 

Bevor Sie in das Textfeld eingeben, klicken Sie auf den Link "show scope". In der Konsole (ich verwende Chrome) können Sie den Bereich "Kind" erweitern und sehen, dass er noch keine testvalue -Eigenschaft enthält (was ich überraschend finde, weil ich nicht weiß, wie es den "Anfangswert" anzeigt) in der Textbox).Sie können das $ parent-Element erweitern, und Sie sehen die testvalue-Eigenschaft dort - eine Eigenschaft mit diesem Namen scheint zu diesem Zeitpunkt nur im übergeordneten Bereich zu sein.

Löschen Sie jetzt die Konsole, geben Sie sie in das Textfeld ein und klicken Sie erneut auf den Link "show scope". Sie werden sehen, dass der Bereich "Child" jetzt eine neue testvalue -Eigenschaft hat. Er überschattet/verbirgt die übergeordnete Eigenschaft. So sehen die Dinge im untergeordneten Bereich die testvalue-Eigenschaft des untergeordneten Bereichs und die Objekte im übergeordneten Bereich sehen die testvalue-Eigenschaft des übergeordneten Bereichs.

Update: FYI, ich schrieb vor kurzem eine umfangreiche Antwort/Artikel über Umfang prototypische Vererbung, die die oben genannten Konzepte in viel mehr ins Detail, mit vielen Bildern erklärt: What are the nuances of scope prototypal/prototypical inheritance in AngularJS?

+0

Danke für diese Erklärung Mark. Es hat einiges für mich aufgeräumt. – Caleb

Verwandte Themen