277

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

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

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

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

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

谢谢!

更新:似乎我实际上已经解决了这个问题(之前不得不想出一些解决方法):只需将我的属性名称从更改searchTextsearch.text,然后在控制器中定义空$scope.search = {};对象,瞧……不知道为什么它在工作尽管 ;]

4

14 回答 14

638

“如果你使用 ng-model,你必须有一个点。”
让你的模型指向一个 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。子范围创建它自己的值,并产生名称冲突,如下所示

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

于 2014-03-31T17:54:36.543 回答
74

控制器作为版本(推荐)

这里的模板

<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 或更高版本的组件

########

方法(不推荐)

不建议这样做,因为字符串是原始的,强烈建议使用对象来代替

在你的标记中试试这个

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

这在你的控制器中

$scope.check = function (searchText) {
    console.log(searchText);
}
于 2012-09-29T08:14:39.000 回答
59

在 Mastering Web Application Development with AngularJS book p.19 中,写到

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

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

于 2013-11-20T15:23:27.293 回答
46

使用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使用它,它实际上是指父 $scope,因为 javascript 的词法范围功能。

如果有人以这种方式测试并通知我们,那就太好了。

于 2014-09-21T11:32:05.680 回答
14

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

$scope.model = {}

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

希望这对你有用!

于 2016-01-21T17:07:39.623 回答
10

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

于 2013-04-03T02:04:22.417 回答
6

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

我已经(我假设!)完全按照您正在做的事情做,而且它似乎正在工作。你能检查一下什么不适合你吗?

于 2012-09-27T11:12:39.990 回答
6

由于没有人提到这一点,因此可以通过添加$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!
    };
}]);
于 2016-08-18T13:22:15.970 回答
5

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

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

});

我希望它会有所帮助

于 2016-02-21T15:24:18.133 回答
2

我刚刚使用绑定到 body-element 的 root_controller 遇到了这个问题。然后我将 ng-view 与角度路由器一起使用。问题是 Angular 在将 html 插入 ng-view 元素时总是会创建一个新范围。因此,我的“检查”功能是在由我的 ng-model 元素修改的范围的父范围上定义的。

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

于 2014-03-13T07:12:42.670 回答
2

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

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

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

这样,该值仅设置为 '$scope.searchText' 值,并且在输入值更改时会更新。

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

于 2017-08-15T13:31:41.577 回答
2

You can do that to enable search in ng-keypress enter for input text and in ng-click for the icon:

<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);
        }
    }
于 2015-09-04T09:28:53.463 回答
2

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

警报(this.ModelName);

于 2017-12-30T08:57:51.093 回答
-1

为表单控件提供名称属性

于 2021-03-23T11:49:30.780 回答