【问题标题】:Why doesn't my Angular ngModel example throw an error?为什么我的 Angular ngModel 示例不抛出错误?
【发布时间】:2014-06-05 02:00:32
【问题描述】:

我已经阅读了一些关于 Angular $scope 的 SO 响应以及它是如何成为一个普通的旧 JavaScript 对象的,这意味着它将遵循 JS 的原型继承 (What are the nuances of scope prototypal / prototypical inheritance in AngularJS?)

既然是这样,我很好奇为什么我的下面的例子没有抛出错误:

<!doctype html>
<html ng-app='MyApp'>
<head>
  <meta charset='utf-8'>
  <title>Egghead</title>
  <script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js'></script>
  <script>
    var app = angular.module('MyApp', []);
    app.controller('MainCtrl', ['$scope', function ($scope) {

    }])
  </script>
</head>
<body>
  <div ng-controller='MainCtrl'>
    <input type='text' ng-model='data.message'>
    <p>{{ data.message }}</p>
  </div>
</body>
</html>

基于原型继承,这是我期望发生的:

  1. 当 MainCtrl 被调用时,它将为 MainCtrl 及其对应的视图创建一个 $scope 对象。
  2. 每当您在输入框中输入内容时,它都会将一些字符串绑定到 $scope.data.message。
  3. 但是,为了做到这一点,JavaScript 的第一步是尝试解析 $scope.data。
  4. 由于 MainCtrl 函数没有数据属性,它会尝试在 rootScope 中查找数据属性。
  5. 由于 rootScope 没有数据属性,$scope.data 应该解析为“未定义”。
  6. 最后,如果您尝试分配给 undefined.message,这应该会引发错误。

但是,代码可以正常工作并且数据已正确绑定。有人可以帮助解开为什么这不会给我带来错误吗?

【问题讨论】:

  • 将此作为评论留下,因为我确信会有更多技术响应。从我读过的内容来看,直到抛出错误为止,您都是正确的。 Angular 没有尝试分配给 undefined.message 并抛出错误,而是检测到它是未定义的并在范围内创建它,然后分配值。

标签: javascript angularjs angularjs-scope angular-ngmodel


【解决方案1】:

之所以没有失败,我的意思是ngModel,是因为它是一个双向数据绑定指令。您可以在其他帖子中阅读更多相关信息:

What's the difference between ng-model and ng-bind

但是解释这种行为的更简单的方法是,如果在ngModel 中使用了一个变量,即使它不存在,你也将它声明为范围的一部分。

【讨论】:

    【解决方案2】:

    发表我最初的评论是因为我不是 100%,但是在检查了文档之后,这是因为......

    “ngModel 将尝试绑定到通过在当前范围内评估表达式给出的属性。如果该属性在此范围内尚不存在,它将被隐式创建并添加到范围内。”

    因此,如果该属性不存在,它将在为其赋值时创建。

    源代码:here

    【讨论】:

    • 感谢您将我带回文档!这解释了它,但我的后续问题是“数据”属性是否将分配给 MainCtrl 的 $scope 对象或 rootScope 对象。我不确定的原因是因为 Angular 似乎正在沿着作用域链向上走,它处理的最后一个作用域对象似乎是 rootScope 对象。
    • 数据会绑定到你所在的控制器的范围内,所以在本例中为 MainCtrl。我这么说是因为文档说“通过评估当前范围上的表达式”,然后继续说“如果该属性在此范围内不存在”,所以这是指当前范围,它不是 $rootScope 而是mainCtrl 范围。
    • 感谢泰勒的帮助!
    猜你喜欢
    • 2015-09-01
    • 2017-12-08
    • 2021-11-20
    • 2020-11-14
    • 2019-06-03
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多