controller: function($scope,$element) { var panes = $scope.panes = []; $scope.select = function(pane) { angular.forEach(panes,function(pane) { pane.selected = false; }); pane.selected = true; } this.addPane = function(pane) { if (panes.length == 0) $scope.select(pane); panes.push(pane); } }
注意如何将select方法添加到$ scope,但addPane方法添加到此。如果我将其更改为$ scope.addPane,代码断开。
文档说,事实上有一个区别,但它没有提到什么区别是:
PrevIoUs versions of Angular (pre 1.0 RC) allowed you to use
this
interchangeably with the$scope
method,but this is no longer the case. Inside of methods defined on the scopethis
and$scope
are interchangeable (angular setsthis
to$scope
),but not otherwise inside your controller constructor.
这和$ scope如何工作在AngularJS控制器?
“How does
this
and$scope
work in AngularJS controllers?”
简短答案:
>这个
>当调用控制器构造函数时,这是控制器。
>当调用在$ scope对象上定义的函数时,这是“调用函数时有效的范围”。这可能(或可能不是!)是函数定义的$范围。所以,在函数内部,这个和$ scope可能不一样。
> $ scope
>每个控制器都有一个关联的$ scope对象。
>控制器(构造函数)函数负责在其相关联的$ scope上设置模型属性和函数/行为。
>只有在此$ scope对象(以及父范围对象,如果原型继承正在运行)中定义的方法可以从HTML /视图访问。例如,从ng-click,过滤器等
长答案:
控制器函数是JavaScript构造函数。当构造函数执行时(例如,当视图加载时),这个(即“函数上下文”)被设置为控制器对象。所以在“tabs”控制器构造函数中,当addPane函数被创建时
this.addPane = function(pane) { ... }
它是在控制器对象上创建的,而不是在$ scope上。视图看不到addPane函数 – 它们只能访问在$ scope上定义的函数。换句话说,在HTML中,这将不工作:
<a ng-click="addPane(newPane)">won't work</a>
在“tabs”控制器构造函数执行后,我们有以下:
虚线黑色线表示原型继承 – 孤立范围从原型继承自Scope.(它不从原型继承自HTML中遇到指令的有效范围。)
现在,pane指令的链接函数想要与tabs指令通信(这真的意味着它需要影响标签以某种方式隔离$ scope)。可以使用事件,但另一种机制是让pane指令需要tabs控制器。 (似乎没有机制让窗格指令要求标签$ scope。)
所以,这提出了一个问题:如果我们只有访问tabs控制器,我们如何访问的选项卡隔离$ scope(这是我们真正想要的)?
嗯,红色的虚线是答案。 addPane()函数的“scope”(我指的是JavaScript的函数作用域/ closures这里)给了函数访问tabs $ scope。也就是说,addPane()可以访问上图中的“tabs IsolateScope”,因为定义了addPane()时创建了一个闭包。 (如果我们在tabs $ scope对象上定义addPane(),则pane指令将无法访问此函数,因此它将无法与tabs $ scope进行通信)。
回答你的问题的另一部分:$ scope如何在控制器工作:?
在$ scope上定义的函数中,这被设置为“$ scope在效果中/当函数被调用时”。假设我们有以下HTML:
<div ng-controller="ParentCtrl"> <a ng-click="logThisAndScope()">log "this" and $scope</a> - parent scope <div ng-controller="ChildCtrl"> <a ng-click="logThisAndScope()">log "this" and $scope</a> - child scope </div> </div>
和ParentCtrl(Solely)有
$scope.logThisAndScope = function() { console.log(this,$scope) }
单击第一个链接将显示此和$ scope是相同的,因为“函数调用时有效的范围”是与ParentCtrl相关联的范围。
点击第二个链接会显示这个和$ scope不一样,因为“函数调用时有效的范围”是与ChildCtrl相关联的范围。所以这里,这是设置为ChildCtrl的$ scope。在方法内部,$ scope仍然是ParentCtrl的$ scope。
我试图不使用在$ scope定义的函数内部,因为它变得混淆哪个$ scope正在受到影响,特别是考虑到ng-repeat,ng-include,ng-switch和directives都可以创建自己的子范围。