Ng模型不更新控制器值

时间:2012-09-27 09:35:25

标签: javascript angularjs data-binding angular-ngmodel

可能是愚蠢的问题,但我的html表单只有简单的输入和按钮:

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

然后在控制器中(从routeProvider调用模板和控制器):

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

为什么我在单击按钮时会在控制台中看到视图更新正确但未定义?

谢谢!

更新: 好像我已经解决了这个问题(之前不得不提出一些解决方法): 只需要将我的属性名称从searchText更改为search.text,然后在控制器中定义空的$scope.search = {};对象并瞧...不知道为什么它正在工作;]

14 个答案:

答案 0 :(得分:592)

&#34;如果您使用ng-model,则必须有一个点。&#34;
让你的模型指向一个object.property,你会很高兴。

<强>控制器

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

<强>模板

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

当孩子范围在起作用时会发生这种情况 - 如子路线或ng-repeats。 子范围创造了它自己的价值,名称冲突诞生as illustrated here

有关详情,请参阅此视频剪辑:https://www.youtube.com/watch?v=SBwoFkRjZvE&t=3m15s

答案 1 :(得分:70)

控制器版本(推荐)

这里是模板

<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>

JS

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

示例:http://codepen.io/Damax/pen/rjawoO

最好使用Angular 2.x或Angular 1.5或upper

的组件 ########

方式(不推荐)

不建议这样做,因为字符串是基元,强烈建议使用对象

在你的标记中试试这个

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

这在你的控制器中

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

答案 2 :(得分:56)

在使用AngularJS第19页的“掌握Web应用程序开发”中,编写了

  

避免直接绑定到作用域的属性。双向数据绑定到   对象的属性(在作用域上公开)是一种首选方法。作为一个   经验法则,你应该在表达式中提供一个点   ng-model指令(例如,ng-model =“thing.name”)。

范围只是JavaScript对象,它们模仿dom层次结构。根据{{​​3}},范围属性通过范围分隔。为避免这种情况,点符号应用于绑定ng-models。

答案 3 :(得分:41)

使用this代替$scope有效。

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>

编辑:在撰写此答案时,我的情况要比这复杂得多。评论之后,我试图重现它,以了解它的工作原理,但没有运气。我想某种方式(不知道为什么)生成了一个新的子范围,this引用了该范围。但是如果使用$scope,则实际上是因为javascript的lexical scope功能而引用了父$ scope。

如果遇到此问题的人以这种方式进行测试并通知我们,那就太棒了。

答案 4 :(得分:10)

我遇到了同样的问题,这是因为我没有先在控制器顶部声明空白对象:

$scope.model = {}

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

希望这对你有用!

答案 5 :(得分:9)

在处理非平凡视图(存在嵌套范围)时遇到了同样的问题。最后发现,由于java脚本基于原型的继承的性质,在开发AngularJS应用程序时这是一个众所周知的棘手问题。 AngularJS嵌套作用域是通过此机制创建的。并且从ng-model创建的值被放置在子范围中,而不是说父范围(可能是注入控制器的范围)不会看到该值,该值也将影响在父范围中定义的具有相同名称的任何属性,如果不是使用dot来强制执行原型引用访问。有关详细信息,请查看特定的在线视频以说明此问题,http://egghead.io/video/angularjs-the-dot/以及后续评论。

答案 6 :(得分:5)

看看这个小提琴http://jsfiddle.net/ganarajpr/MSjqL/

我(我假设!)完成了你正在做的事情,它似乎正在发挥作用。你能检查一下这里没有的东西吗?

答案 7 :(得分:4)

对我来说,问题是通过将我的数据存入一个对象来解决的(这里是&#34;数据&#34;)。

&#13;
&#13;
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'
   }
   

});
&#13;
&#13;
&#13;

我跳它会帮助

答案 8 :(得分:4)

由于没有人提到这个问题,可以通过将$parent添加到绑定属性

来解决问题
<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>

和控制器

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

    $scope.BankLogin = function () {
        console.log($scope.ssn); // works!
    };
}]);

答案 9 :(得分:1)

我只是使用绑定到body-element的root_controller来解决这个问题。然后我用角度路由器使用ng-view。问题是,当它将html插入到ng-view元素时,angular ALWAYS会创建一个新范围。因此,我的检查&#34;函数是在我的ng-model元素修改的范围的父范围上定义的。

要解决此问题,只需在路由加载的html内容中使用专用控制器。

答案 10 :(得分:1)

您可以执行此操作以在ng-keypress输入中输入输入文本,在ng-click中输入图标:

<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);
        }
    }

答案 11 :(得分:1)

我遇到了同样的问题 正确的方法是设置&#39; searchText&#39;成为对象内的属性。

但是,如果我想保留原样的字符串怎么办?好吧,我尝试了这里提到的每一种方法,没有任何效果 但后来我注意到问题只出现在启动中,所以我只是设置了value属性并且它有效。

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

这种方式只是设置为&#39; $ scope.searchText&#39;值,并在输入值更改时更新。

我知道这是一种解决方法,但它对我有用..

答案 12 :(得分:1)

我遇到了同样的问题...... 对我有用的解决方案是使用此关键字..........

警报(this.ModelName);

答案 13 :(得分:-1)

为表单控件提供名称属性