2014-04-21 45 views
1

我已经阅读了有关角$范围几个SO反应,以及它如何是一个普通的旧JavaScript对象,这意味着它会跟JS的原型继承(What are the nuances of scope prototypal/prototypical inheritance in AngularJS?为什么我的Angular ngModel示例不会引发错误?

既然是这样的话,我很好奇,为什么我的下面的例子不会抛出一个错误:

<!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一个$范围对象及其相应的观点。
  2. 无论何时输入到输入框中,它都会将一些字符串绑定到$ scope.data.message。
  3. 但是,为了做到这一点,JavaScript中的第一步将尝试解决$ scope.data。
  4. 由于MainCtrl函数没有数据属性,它将尝试在rootScope中查找数据属性。
  5. 由于rootScope没有数据属性,$ scope.data应该解析为'undefined'。
  6. 最后,如果您尝试分配给undefined.message,则会引发错误。

但是,代码愉快地工作和数据绑定正确。有人可以帮助解开为什么这不是给我抛出一个错误?

+1

把这个作为一个评论,因为我敢肯定有更多的技术响应。从我读过的内容来看,你是正确的,直到抛出错误。角色不是试图分配给undefined.message并抛出错误,而是检测到它是未定义的,并在该范围上创建它,然后分配该值。 –

回答

1

使我原来的评论,因为我不是100%,但检查文档之后,那是因为...

“ngModel会尝试绑定到通过对当前范围计算表达式给出的属性。如果该属性尚未存在于此范围内,则它将隐式创建并添加到范围中。“

所以,如果该属性不存在,它会创建时,然后将值分配给它。

源:here

+0

感谢您指点我回到文档!这解释了它,但后来的问题是'data'属性是否会被分配给MainCtrl的$ scope对象或rootScope对象。我不确定的原因是因为它看起来像Angular正在走上范围链,它处理的最后一个范围对象似乎是rootScope对象。 – wmock

+1

数据将被绑定到您所在控制器的范围内,因此在此示例MainCtrl中。我说因为文档说'通过评估CURRENT SCOPE上的表达式'它然后继续说'如果属性不存在于THIS范围',所以这是指当前作用域不是$ rootScope,但是mainCtrl范围。 –

+0

谢谢泰勒的帮助! – wmock

0

它不会失败的原因,我的意思是ngModel这是因为它是一种双向数据绑定指令。你可以阅读更多关于此此的其他职位:

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

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

相关问题