Ng-model ne met pas à jour la valeur du contrôleur

question probablement stupide, mais j'ai ma forme html avec Simple entrée et bouton:

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

puis dans le controller (template et controller sont appelés à partir de routeProvider):

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

Pourquoi est-ce que je vois la vue mise à jour correctement mais non définie dans la console en cliquant sur le bouton?

Merci!

mise à jour: Il semble que j'ai effectivement résolu ce problème (avant dû venir avec quelques solutions de rechange) avec: J'ai seulement dû changer mon nom de propriété de searchText à search.text , puis Définir l'objet vide $scope.search = {}; dans le contrôleur et voila...

248
demandé sur Damjan Pavlica 2012-09-27 13:35:25

13 réponses

contrôleur as version (recommandée)

voici le modèle

<div ng-app="example" ng-controller="myController as $ctrl">
    <input type="text" ng-model="$ctrl.searchText" />
    <button ng-click="$ctrl.check()">Check!</button>
    {{ $ctrl.searchText }}
</div>

The JS

angular.module('example', [])
  .controller('myController', function() {
    var vm = this;
    vm.check = function () {
      console.log(vm.searchText);
    };
  });

un exemple: http://codepen.io/Damax/pen/rjawoO

le mieux sera d'utiliser le composant avec L'angle 2.x ou angulaire 1,5 ou supérieure

########

Vieux "151960920 (NON recommandé)

ceci N'est pas recommandé car une chaîne est une primitive, fortement recommandé d'utiliser un objet à la place

Essayez ceci dans votre balisage

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

et ceci dans votre contrôleur

$scope.check = function (searchText) {
    console.log(searchText);
}
64
répondu Damax 2017-01-05 09:17:54

"Si vous utilisez ng-model, vous devez avoir un point là."

Faites pointer votre modèle vers un objet.de la propriété et vous serez bon d'aller.

contrôleur

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

Modèle

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

cela se produit quand les lunettes de l'enfant sont dans les routes de l'enfant play - like ou ng-se répète. L'enfant-portée crée sa propre valeur et un conflit de nom est né comme illustré ici :



voir ce clip vidéo pour plus d'informations: https://www.youtube.com/watch?v=SBwoFkRjZvE&t=3m15s

579
répondu Will Stern 2015-06-30 19:57:36

in Mastering Web Application Development with AngularJS book p. 19, Il est écrit que

éviter les reliures directes aux propriétés de scope. Liaison bidirectionnelle des données les propriétés de l'objet (exposé sur une portée) est une approche privilégiée. En tant que règle générale, vous devriez avoir un point dans une expression à la ng-model directive (par exemple, ng-model="thing.nom").

Scopes sont juste des objets JavaScript, et ils imitent la hiérarchie dom. Selon héritage Prototype JavaScript , les propriétés des portées sont séparées par des portées. Pour éviter cela, pointillé doit utiliser pour lier ng-modèles.

55
répondu efirat 2013-11-20 15:23:27

utilisant this au lieu de $scope œuvres.

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>

Edit: au moment d'écrire cette réponse, j'avais une situation beaucoup plus compliquée que celle-ci. Après les commentaires, j'ai essayé de le reproduire pour comprendre pourquoi il fonctionne, mais pas de chance. Je pense que d'une certaine manière (ne sait pas vraiment pourquoi) un nouvel enfant est généré et this s'entend de la portée. Mais si $scope est utilisé, il désigne en fait parent $scope en raison de la fonctionnalité lexical scope de javascript.

serait génial si quelqu'un ayant ce problème Teste de cette façon et nous informe.

39
répondu Feyyaz 2017-05-23 12:02:49

j'ai eu le même problème et c'était dû au fait que je n'ai pas déclaré l'objet vide en premier au sommet de mon contrôleur:

$scope.model = {}

<input ng-model="model.firstProperty">

J'espère que ça va marcher pour vous!

10
répondu Millsionaire 2017-04-15 11:59:23

je suis tombé sur la même question en traitant d'une vue non-triviale (il ya des portées emboîtées). Et finalement découvert cela est une chose connue délicate lors du développement de L'application AngularJS en raison de la nature de prototype-basé héritage de java-script. AngularJS scopes imbriqués sont créés par ce mécanisme. Et la valeur créée à partir du modèle ng est placée dans le champ enfants, sans dire que le champ parent (peut-être celui injecté dans le contrôleur) ne verra pas la valeur, la valeur sera aussi shadow toute propriété avec le même nom défini dans le champ d'application parent si vous n'utilisez pas dot pour appliquer un accès de référence prototype. Pour plus de détails, consultez la vidéo en ligne spécifique pour illustrer ce numéro, http://egghead.io/video/angularjs-the-dot / et commente la suite.

9
répondu Roger Jin 2013-04-03 02:04:22

Regardez ce violon http://jsfiddle.net/ganarajpr/MSjqL/

j'ai ( je suppose! ) fait exactement ce que tu faisais et il semble fonctionner. Pouvez-vous vérifier ce qui ne fonctionne pas ici pour vous?

5
répondu ganaraj 2012-09-27 11:12:39

pour moi le problème a été résolu en stockant mes données dans un objet (ici "données").

NgApp.controller('MyController', function($scope) {

   $scope.my_title = ""; // This don't work in ng-click function called

   $scope.datas = {
      'my_title' : "",
   };

   $scope.doAction = function() {
         console.log($scope.my_title); // bad value
         console.log($scope.datas.my_title); // Good Value binded by'ng-model'
   }
   

});

je Hop il aidera

4
répondu Plici Stéphane 2016-02-21 15:24:18

comme personne ne l'a mentionné, le problème peut être résolu en ajoutant $parent à la propriété liée

<div ng-controller="LoginController">
    <input type="text" name="login" class="form-control" ng-model="$parent.ssn" ng-pattern="/\d{6,8}-\d{4}|\d{10,12}/" ng-required="true" />
    <button class="button-big" type="submit" ng-click="BankLogin()" ng-disabled="!bankidForm.login.$valid">Logga in</button>
</div>

et le contrôleur

app.controller("LoginController", ['$scope', function ($scope) {
    $scope.ssn = '';

    $scope.BankLogin = function () {
        console.log($scope.ssn); // works!
    };
}]);
3
répondu Eric Herlitz 2016-08-18 13:22:15

je viens d'avoir ce même problème en utilisant un root_controller lié à l'élément du corps. Puis j'ai utilisé ng-view avec le routeur angulaire. Le problème est qu'angular crée toujours une nouvelle portée quand il insère le html dans l'élément ng-view. En conséquence, ma fonction "check" a été définie sur la portée initiale de la portée qui a été modifiée par mon élément ng-model.

pour résoudre le problème, il suffit d'utiliser un contrôleur dédié dans le contenu html chargé par route.

1
répondu moritz 2014-03-13 07:12:42

vous pouvez faire cela pour permettre la recherche dans ng-keypress ENTRER pour le texte d'entrée et dans ng-click pour l'icône:

<input type="text" ng-model="searchText" ng-keypress="keyEnter(this,$event)" />
<button ng-click="check(searchText)">Check!</button>

in the controller
$scope.search = function (searchText) {
        console.log(searchText);
    }
    $scope.keyEnter = function (serachText,$event) {
        var keyCode = $event.which || $event.keyCode;
        if (keyCode === 13) {//KeyCode for Enter key
           console.log(searchText);
        }
    }
1
répondu Naoufal Gaffa 2015-09-04 09:50:06

j'ai eu le même problème.

La bonne façon serait de définir le 'searchText' comme une propriété à l'intérieur d'un objet.

mais si je veux le laisser tel quel, une ficelle? j'ai essayé toutes les méthodes mentionnées ici, rien n'a marché.

Mais ensuite j'ai remarqué que le problème est seulement dans l'initiation, donc j'ai juste mis l'attribut de valeur et ça a marché.

<input type="text" ng-model="searchText" value={{searchText}} />

de cette façon la valeur est mise à '$champ d'application.searchText ' valeur et il est mis à jour lorsque la valeur d'entrée change.

je sais que c'est une solution, mais ça a marché pour moi..

1
répondu Hike Nalbandyan 2017-08-15 13:31:41

je faisais face au même problème... La résolution qui a fonctionné pour moi est d'utiliser ce mot-clé..........

alert(ce.ModelName);

1
répondu SnktJavaMaster 2017-12-30 08:57:51