这里我从本教程中学到了:
http://egghead.io/lessons/angularjs-the-dot
<!DOCTYPE html>
<html>
<head>
<title>AngularJS Tutorials</title>
<link rel="stylesheet" href="vendor/foundation/foundation.min.css">
</head>
<body>
<div ng-app="">
<input type="text" ng-model="data.message">
<h1>{{data.message}}</h1>
<div ng-controller="FirstCtrl">
<input type="text" ng-model="data.message">
<h1>{{data.message}}</h1>
</div>
<div ng-controller="SecondCtrl">
<input type="text" ng-model="data.message">
<h1>{{data.message}}</h1>
</div>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.min.js"></script>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
Main.js
function FirstCtrl($scope){
}
function SecondCtrl($scope){
}
现在加载页面。如果我尝试在第一个输入字段中输入数据,它会更新所有h1标签和其他输入字段。 在第二或第三个输入字段中输入数据时会发生相同的情况。
现在,如果我们刷新页面并首先在第二个输入字段中输入数据 然后它只更新第二个h1标签。我不喜欢 - 它的相同代码的不同结果。为什么它取决于他先做的用户行为?这可能会导致很多错误。
答案 0 :(得分:2)
这是因为变量data
未在范围内的任何位置定义,而是在首次编辑它的最顶层范围内创建。
对比这个例子:http://plnkr.co/edit/mqtPaMsH2xVMJaW3mEkX?p=preview
这里,控制器是:
function FirstCtrl($scope){
}
function SecondCtrl($scope){
}
function RootCtrl($scope) {
$scope.data = {};
}
模板是:
<div ng-controller="RootCtrl">
<input type="text" ng-model="data.message" />
<h1>{{data.message}}</h1>
<div ng-controller="FirstCtrl">
<input type="text" ng-model="data.message" />
<h1>{{data.message}}</h1>
</div>
<div ng-controller="SecondCtrl">
<input type="text" ng-model="data.message" />
<h1>{{data.message}}</h1>
</div>
</div>
此处,由于我在最顶层范围内明确定义了data
变量,因此不再在FirstCtrl
或SecondCtrl
的范围内创建变量。但是,如果我省略$scope.data = {}
上的定义RootCtrl
,它将在动态创建,并在最需要定义的范围内创建,而不一定在RootCtrl
的范围内。如果您随后在data.message
的范围内编辑RootCtrl
,则会重新创建并继承任何没有该范围的范围。
查看developer guides on GitHub以获取有关范围继承的更详细说明。在控制器中。
答案 1 :(得分:2)
这是范围继承行为。当角度遇到ng控制器时,它将创建 新范围 ,继承自 当前范围 。< / p>
在您的示例中,有 FirstCtrl的范围和 SecondCtrl的范围,它们都继承自 rootScope 并且 被隔离< / em> 彼此。
如果我尝试在第一个输入字段中输入数据,它会更新所有h1标记 和其他输入字段。
在这种情况下,它将在 rootScope 上创建/更新 data.message (因为它不在ng-controller中),由继承FirstCtrl的范围和 SecondCtrl的范围,因为在您的代码中, FirstCtrl的范围和 SecondCtrl的范围中不存在 data.message
现在,如果我们刷新页面并首先在第二个输入字段中输入数据 然后它只更新第二个h1标签。
在这种情况下,它将在 FirstCtrl的范围上创建/更新 data.message 。 rootScope和 SecondCtrl的范围 无法识别此更新的 。