282 votes

Ng-modèle ne met pas à jour la valeur du contrôleur

Probablement question idiote, mais j'ai mon formulaire html avec entrée simple et bouton:

<input type="text" ng-model="searchText" />
<button ng-click="check()">Check!</button>
{{ searchText }}

Puis dans le contrôleur (modèle et le contrôleur sont appelées à partir de routeProvider):

$scope.check = function () {
    console.log($scope.searchText);
}

Pourquoi dois-je voir le point de vue mis à jour correctement, mais non défini dans la console en cliquant sur le bouton?

Merci!

Mise à jour: Il semble que j'ai effectivement résolu ce problème (avant fallait trouver quelques solutions de contournement) avec: N'avait qu'à changer mon nom de la propriété à partir de searchText de search.text, puis de définir vide $scope.search = {}; objet dans le contrôleur et le tour est joué... n'Ai aucune idée de pourquoi ça fonctionne bien ;]

645voto

Will Stern Points 1727

Vous devez utiliser une propriété enfant d'un objet existant pour éviter cette bizarrerie dans Javascript:

Manette

 $scope.formData = {};
$scope.check = function () {
  console.log($scope.formData.searchText); //works
}
 

Modèle

 <input ng-model="formData.searchText"/>
<button ng-click="check()">Check!</button>
 

74voto

Damax Points 468

Essayez ceci dans votre balisage

 <input type="text" ng-model="searchText" />
<button ng-click="check(searchText)">Check!</button>
{{ searchText }}
 

et cela dans votre contrôleur

 $scope.check = function (searchText) {
    console.log(searchText);
}
 

61voto

kirlisakal Points 628

Dans la maîtrise de Développement d'Application Web avec AngularJS livre p.Le 19, il est écrit que

Évitez le contact direct avec des liaisons à la portée de ses propriétés. Les deux sens de la liaison de données pour propriétés de l'objet (exposé sur un champ d'application) est une approche privilégiée. En tant que règle générale, vous devriez avoir un point dans une expression à la ng-modèle de la directive (par exemple, ng-model="chose.name").

Les étendues sont juste des objets JavaScript, et ils imitent les dom hiérarchie. Selon JavaScript Prototype de l'Héritage, des étendues de propriétés sont séparées par des étendues. Pour éviter cela, la notation de point à utiliser pour lier ng-modèles.

46voto

Feyyaz Points 788

En utilisant this au lieu de $scope fonctionne.

 function AppCtrl($scope){
  $scope.searchText = "";
  $scope.check = function () {
    console.log("You typed '" + this.searchText + "'"); // used 'this' instead of $scope
  }
} 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app>
  <div ng-controller="AppCtrl">
    <input ng-model="searchText"/>
    <button ng-click="check()">Write console log</button>
  </div>
</div> 

10voto

Roger Jin Points 180

Je suis tombé sur le même problème quand il s'agit de non-trivial de vue (il n'y sont imbriqués les étendues). Et enfin découvert c'est un chose la plus délicate lors de l'élaboration d'AngularJS application en raison de la nature de prototype basé sur l'héritage de java-script. AngularJS imbriqués les étendues sont créés par le biais de ce mécanisme. Et la valeur créée à partir de ng-model est placé dans de la portée des enfants, ne pas dire parent (peut-être celle injectée dans le contrôleur) ne verrez pas la valeur, la valeur sera aussi l'ombre toute la propriété avec le même nom défini dans la portée parent si pas utiliser de point d'appliquer un prototype de référence d'accès. Pour plus de détails, l'extraction de la vidéo en ligne spécifique pour illustrer ce problème, http://egghead.io/video/angularjs-the-dot/ et commentaires suivants.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X