Relation ng-model et ng-repeat et compréhension de la portée

<!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> </head> <body> <div ng-app="myApp" ng-controller="customersCtrl"> <ul> <!--Inside ng-repeat--> <li ng-repeat="x in d"> {{$index}} <input ng-model="val">{{val}} </li> <!--Inside ng-repeat--> <br><br><br> <!--Outside ng-repeat--> Outer<input ng-model="val">{{val}} <!--Outside ng-repeat--> </ul> </div> <script> var app = angular.module('myApp', []); app.controller('customersCtrl', function($scope) { $scope.d=[1,2,3,4,5]; }); </script> </body> </html> 

Dans ce cas, j'ai cinq ng de champ de saisie répété avec ng-model comme val. Il y a de nombreux scénarios auxquels j'ai rencontré lorsque j'ai suivi ce code

Scénario 1: ng-model = val est identique pour toutes les cases entrées ng-repeat, mais quand je change dans l'une de ces boîtes de saisie répétées pourquoi elle ne reflète pas toutes les expressions

Scénario 2: si dans les entrées répétées les étendues sont différentes, comment pouvons-nous nous référer à cette portée. Est-ce comme val [o], val [1], val [2] comme ça

Scénario 3: si je change dans le champ de saisie externe sans changer ou enduire le champ de saisie ng répété, il reflète toutes les expressions. Mais si je change dans n'importe quel champ de saisie, prenez 0 et changez la valeur dans le champ de saisie externe de tous les champs de saisie (1,2,3,4) sauf 0 changez … quel est l'accord ici avec la portée et pourquoi la portée est Se comporter comme ça?

C'est parce que ng-repeat rend la portée de l'enfant, ce qui signifie qu'elle hérite de manière prototypique à partir de la portée du conteneur. Si c'est quelque chose de nouveau pour vous, google, il y a beaucoup d'explications pour cela. Ou lisez ceci: https://github.com/angular/angular.js/wiki/Understanding-Scopes

De plus, installez Angular Batarang en chrome pour examiner la portée. Cela vous donne une idée approfondie de ce qui se passe.

Maintenant, comment traiter cela de manière propre – utilisez le contrôleur comme suit:

 <!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> </head> <body> <div ng-app="myApp" ng-controller="customersCtrl as vm"> <ul> <!--Inside ng-repeat--> <li ng-repeat="x in vm.d"> {{$index}} <input ng-model="vm.val">{{vm.val}} </li> <!--Inside ng-repeat--> <br><br><br> <!--Outside ng-repeat--> Outer<input ng-model="vm.val">{{vm.val}} <!--Outside ng-repeat--> </ul> </div> <script> var app = angular.module('myApp', []); app.controller('customersCtrl', function($scope) { this.d=[1,2,3,4,5]; }); </script> </body> </html> 

Explication détaillée

Pensez aux étendues comme suit (très grossière mise en œuvre cependant):

 function ParentScope(){ this.val = "parent"; } function ChildScope(){ } ChildScope.prototype = new ParentScope(); ChildScope.prototype.constructor = ChildScope; var childScope = new ChildScope(); 

Explication de vos scénarios:

1: Chaque fois que vous commencez à taper dans la boîte de dialogue répétée ng, ng-model essaie d'écrire sur la propriété "val" de childScope, qui n'est pas disponible directement sur l'objet enfant mais sur le proto de l'objet.

 childScope.val = "child" 

Cette déclaration crée une nouvelle propriété sur un objet enfant et masque la propriété parent.

3: Chaque fois que vous tapez n'importe quoi dans la zone de texte en dehors de ng-repeat, cela modifie le "val" dans Parent Scope et que les champs enfants ont été hérités de manière prototypique de la portée parent, ils peuvent lire cette propriété et, par conséquent, ng-model essaie de lire Cette propriété et se lie à la boîte de texte, c'est pourquoi toutes les zones de texte répétées ng montrent cette valeur. Mais, dès que vous tapez dans la boîte de texte répétée ng, elle tente de nouveau d'écrire sur la portée de l'enfant, mais finit par créer une nouvelle propriété, cachant la propriété parent.

J'espère que ça l'explique bien.

Pour le scénario 2: si vous avez besoin d'une variable de portée différente, vous devez faire comme ci-dessous:

 <li ng-repeat="x in d"> <input type="text" ng-model="val[$index]" ng-init="val[$index] = x"> </li> 

Pour le scénario 1 et 3: le champ de saisie ng-répété n'est pas initialisé en premier jusqu'à ce que vous soyez la valeur.