2014-04-21 73 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使用你也聲明爲範圍的一部分,即使它不存在。

相關問題