来自Step 3 of AngularJS Tutorial的伟大理论片段中,那篇文章让我想知道:
- 范围,粘合我们的控制器和模板 一起进入动态视图,不是与其他部分隔离开来的 页。这意味着一个随机的,无关的变化 页面的不同部分(例如属性名称冲突)可能具有 意外和难以调试的副作用对我们的看法。
醇>
(来自同一链接的未引用的第1部分非常清楚)
我无法想象一个reallife代码示例,说明引用文本中显示的问题。你能告诉我这样一个例子吗?
我自己的猜测是基于继承的范围:
<!doctype html>
<html lang="en" ng-app="phonecatApp">
<head>
...
</head>
<body>
<div ng-controller="PhoneListController">
{{secretObject.dontDareToTouchThat}}
<div ng-controller="PhoneListTwoController">
<ul ng-click="touchThat()">
<li ng-repeat="phone in phones" >
<span>{{phone.name}}</span>
<p>{{phone.snippet}}</p>
</li>
</ul>
</div>
</div>
</body>
</html>
控制器的逻辑:
'use strict';
angular.module('phonecatApp', [])
.controller('PhoneListController', function PhoneListController($scope) {
$scope.secretObject = {
dontDareToTouchThat: 'I"m pure and beautiful'
}
}).controller('PhoneListTwoController', function PhoneListTwoController($scope) {
$scope.touchThat = function(){
$scope.secretObject.dontDareToTouchThat = 'Derp';
}
$scope.phones = [ ... ];
});
但我完全不确定,因为PhoneListTwoController
的可能行为看起来不像“页面不同部分的随机,无关的变化”。一个范围在另一个范围内,操纵外部范围,我认为作者意味着不同的东西,比如两个兄弟范围相互混淆。
所以,再次,我请你用相关的代码示例说明引用的段落。
答案 0 :(得分:1)
该段落由Georgios Kalpakas添加为commit #c2033d7 on May 24。
您可能想问他一个问题。
答案 1 :(得分:1)
这篇教程可能会在这里夸大一点。至少它并不是非常精确。
我创建了一个simple example on plunker,它显示了哪种干扰是可能的,哪些不是干扰。
ng-controller指令确实会创建一个新的子范围。范围上的变量由子范围原型继承。
参考plunker example这意味着由控制器1定义的$ scope.someVariable对控制器2定义的$ scope.someVariable没有任何影响 - (控制器1既不是控制器2的祖先也不是后代)。它还意味着为$ scope.someVariable设置的值不能被其父控制器覆盖,该控制器在其作用域上设置相同的变量。控制器3也是父控制器的后代,它本身不设置$ scope.someVariable。在这种情况下,plunker显示父控制器设置的值在控制器3控制的视图片段中生效。在父控制器范围的所有子范围内,someVariable将作为
Object.getPrototypeOf($scope).someVariable
尽管如此,我同意这个教程,使用将其状态绑定到其控制器实例的组件(在模板中称为$ ctrl)而不是直接使用范围有很多优点。组件具有明确的导入和导出模型。这使它们可以互换并增加了重复使用的机会。
答案 2 :(得分:1)
这确实是指范围继承及其(通常不是直接的)后果。如果你还没有看到它,这是一篇很好的文章:Understanding Scopes
它比你想象的要复杂得多:) 特别是(如教程中所提到的)适用于大型真实世界的应用程序,其中不同的团队在应用程序的不同部分工作,或者某些部分在几个月内保持不变。
要展示一个非常简单的“现实主义”示例(这也不像大型应用程序那么复杂):
想象一下,你正在创办自己的事业;一个电子商店。你想从小做起,所以你现在只有手机和平板电脑。
您只需要一个基本布局 - 标题,导航栏和您的内容区域:
My Cool e-Shop
----------------------------
[Phones] [Tablets]
----------------------------
<CONTENT HERE>
您设置了两条路线 - 一条用于手机,一条用于平板电脑 - 并决定将每个网页的内容封装为类似组件的指令。例如。 #/phones
路由将包含<phone-list></phone-list>
这样的模板,phoneList
指令将如下所示(遗憾的是您从未听说过隔离范围):
.directive('phoneList', function phoneListDirective() {
// DDO
return {
template:
'<h2>Phones</h2>' +
'<ol>' +
'<li ng-repeat="phone in phones">' +
'<b>{{ phone.name }}</b> (OS: {{ phone.os }})' +
'</li>' +
'</ol>',
scope: true,
link: phoneListPostLink
};
// Functions - Definitions
function phoneListPostLink(scope) {
scope.phones = [
{id: 1, name: 'Samsung Galaxy', os: 'Android'},
{id: 2, name: 'Google Nexus', os: 'Android'},
{id: 3, name: 'Nokia Lumia', os: 'Windows'},
{id: 4, name: 'Apple iPhone', os: 'iOS'}
];
}
})
到目前为止,这么好。平板电脑的路线和指令几乎相同,一切正常。
很快,您的可用手机和平板电脑列表就会增长,您需要添加filter
功能。小菜一碟,您只需将以下代码段添加到指令的模板中:
<div>
Filter:
<input type="search" ng-model="search.name" placeholder="Name..." />
<input type="search" ng-model="search.os" placeholder="OS..." />
</div>
<li ng-repeat="phone in phones | filter:search">
就这么简单,您的用户可以按名称和操作系统搜索手机和平板电脑。生意很好,生活很好。
快进几个月,您的网站也在增长,其中包含更多部分和产品类别。您决定“全局搜索”小部件将是导航栏的一个很好的补充。您需要做的就是将以下代码段添加到主模板中:
<div class="search-widget">
<input type="search" ng-model="query" placeholder="Search the entire site..." />
<button ng-click="search(query)" ng-disabled="!query">Search</button>
</div>
(当然,在主控制器上实现$scope.search()
方法......)
其余的是历史:P
在您知道之前,销售很快就会开始下降并且您已经停业。
这是一个简单的POC,可以在实践中看到这一点:Demo
<强> TL;博士强>
使用隔离范围和利润!