首页 文章

Ng模型不更新控制器值

提问于
浏览
251

可能是愚蠢的问题,但我有简单的输入和按钮的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 = {}; 对象并且瞧...不知道为什么它正在工作;]

13 回答

  • 5

    "If you use ng-model, you have to have a dot in there."
    让你的模型指向一个object.property,你会很高兴 .

    Controller

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

    Template

    <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

  • 40

    Controller as 版(推荐)

    这是模板

    <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的组件
    ########
    Old 方式(不推荐)

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

    在你的标记中试试这个

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

    这在你的控制器中

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

    在使用AngularJS第19页掌握Web应用程序开发时,编写了这样的内容

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

    范围只是JavaScript对象,它们模仿dom层次结构 . 根据JavaScript Prototype Inheritance,范围属性通过范围分隔 . 为避免这种情况, dot notation 应该用于绑定ng-models .

  • 9

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

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

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

  • 3

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

    $scope.model = {}
    
    <input ng-model="model.firstProperty">
    

    希望这对你有用!

  • 1

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

  • 1

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

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

  • 1

    对我来说,问题是通过将我的数据存入一个对象(这里是“数据”)来解决的 .

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

    我跳它会有所帮助

  • 4

    由于没有人提到这个问题可以通过将 $parent 添加到bound属性来解决

    <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!
        };
    }]);
    
  • 1

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

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

  • 10

    您可以这样做以在 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);
            }
        }
    
  • 65

    我有同样的问题 .
    正确的方法是将'searchText'设置为对象内的属性 .

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

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

    这样,该值只设置为'$ scope.searchText'值,并在输入值更改时进行更新 .

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

  • 583

    我面临着同样的问题......有效的决议对我来说是使用这个关键字..........

    警报(this.ModelName);

相关问题