Ng-model 不更新控制器值

IT技术 javascript angularjs data-binding angular-ngmodel
2021-02-06 04:28:53

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

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

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

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

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

谢谢!

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

6个回答

“如果你使用 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-repeat。子作用域创建了它自己的值,并产生了名称冲突,如下所示

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

很有帮助。我不确定我会找到一个相对模糊的问题的答案,但这已经死了。
2021-03-15 04:28:53
@Catfish 使用原型继承,每当您写入子属性时,与父属性的引用/连接将不复存在。Angular Scopes 建模的方式,如果您没有点,则在您的子范围内创建一个新属性。该视频更详细地解释了它:youtube.com/watch?v=ZhfUv0spHCY&feature=youtu.be&t=30m
2021-03-25 04:28:53
@ user3677331 它在没有点的情况下工作正常,直到您有一个尝试与之对话的子作用域(例如 ng-repeat 中的一个项目)。假设您的模型名称是“电话”,您的子作用域创建了“电话”,然后您会遇到作用域冲突,因为子作用域有一个“电话”变​​量,因此无法访问父作用域上的“电话”。而如果子作用域创建 user.phone,它将被添加到父级的用户对象中,因此两个作用域都指向同一个对象
2021-03-25 04:28:53
谢谢,我在这个问题上浪费了几个小时 - 幸运的是我找到了这个答案。
2021-04-04 04:28:53
这是真正的答案。
2021-04-10 04:28:53

控制器版本(推荐)

这里的模板

<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);
}
如果我不想使用任何按钮怎么办?例如,我需要在输入时提交
2021-03-19 04:28:53
@HP's411 这是因为字符串是原始类型。当 Angular 分配值时,它会更改指向该值的指针,因此控制器查看旧值,因为它具有指向该值的旧指针。
2021-03-24 04:28:53
这也没有回答“为什么?” 问题。
2021-03-30 04:28:53
这只能以一种方式起作用……如果您想更改 的值searchText怎么办?
2021-04-10 04:28:53
Saniko => 要在输入时提交,您必须在其上使用表单标签和 ng-submit ( docs.angularjs.org/api/ng.directive:ngSubmit )
2021-04-11 04:28:53

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

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

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

感谢您的参考。我认为这是与 ng-model 相关的一个有趣的观点。
2021-04-04 04:28:53

使用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 的词法范围特性。

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

无懈可击,你是天才
2021-03-15 04:28:53
这有效,但是如果您说this.searchText = "something else"或 即使$scope.searchText = "something else",它也不会更新视图。你能解释一下这个问题吗?
2021-03-20 04:28:53
这应该。我使用上面的代码进行了尝试,它更新了视图。
2021-03-29 04:28:53
在这种情况下,为什么我应该使用“this”而不是“$scope”?因为它在我之前的项目中使用 $scope 工作,但这次同样的事情使用 $scope 不起作用。但“这”奏效了。这是为什么?
2021-04-03 04:28:53
看起来附加到的函数$scope创建了一个新的作用域(即在 function 中check()this指的是作为 的子作用域的作用域$scope)。为什么会这样?你能给出一些解释吗?
2021-04-13 04:28:53

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

$scope.model = {}

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

希望这对你有用!