AngularJS控制器中的'this'与$ scope
在AngularJS主页的“创建组件”部分,有这样的例子:
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
方法被添加到this
。 如果我将其更改为$scope.addPane
,则代码会中断。
该文件说实际上存在差异,但它没有提到差异:
角(预1.0 RC)的早期版本允许你使用this
与互换$scope
的方法,但是这不再是这种情况。 在scope和this
$scope
定义的方法的内部是可以互换的(角度将this
设置为$scope
),但是在控制器构造函数中没有。
this
和$scope
在AngularJS控制器中如何工作?
“在AngularJS控制器中this
和$scope
如何工作的?”
简短的回答 :
this
this
是控制器。 $scope
对象上定义的函数时, this
就是“函数被调用时的作用域”。 这可能(或可能不)是函数定义的$scope
。 所以,在函数内部, this
和$scope
可能不一样。 $scope
$scope
对象。 $scope
上设置模型属性和函数/行为。 $scope
对象上定义的方法(和父范围对象,如果原型继承在场)可以从HTML / view中访问。 例如,从ng-click
,过滤器等 长答案 :
控制器函数是一个JavaScript构造函数。 当构造函数执行时(例如,当视图加载时), this
(即“函数上下文”)被设置为控制器对象。 所以在“tabs”控制器构造函数中,当addPane函数被创建时
this.addPane = function(pane) { ... }
它是在控制器对象上创建的,而不是在$ scope上。 视图无法看到addPane函数 - 它们只能访问$ scope上定义的函数。 换句话说,在HTML中,这是行不通的:
<a ng-click="addPane(newPane)">won't work</a>
“tabs”控制器构造函数执行后,我们有以下几点:
黑色虚线表示原型继承 - 隔离范围原型从Scope继承。 (它不会从HTML中遇到指令时有效的范围继承。)
现在,窗格指令的链接函数想要与tabs指令进行通信(这实际上意味着它需要以某种方式影响选项卡隔离$ scope)。 可以使用事件,但另一种机制是让窗格指令require
tab控制器。 (窗格指令似乎没有require
选项卡$范围的机制。)
所以,这引出了一个问题:如果我们只能访问tabs控制器,我们如何访问标签隔离$ scope(这正是我们真正想要的)?
那么红色虚线就是答案。 addPane()函数的“作用域”(我在这里指的是JavaScript的函数作用域/闭包)使函数可以访问标签隔离$ scope。 即,addPane()可以访问上图中的“选项卡IsolateScope”,因为在定义addPane()时创建了一个闭包。 (如果我们在选项卡$ scope对象上定义了addPane(),那么窗格指令将无法访问此函数,因此它无法与选项卡$ scope进行通信。)
回答你的问题的其他部分: how does $scope work in controllers?
:
在$ scope定义的函数中, this
函数被设置为“$ 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
( ParentCtrl
)
$scope.logThisAndScope = function() {
console.log(this, $scope)
}
单击第一个链接将显示this
和$scope
是相同的,因为“函数调用时的作用域”是与ParentCtrl
关联的ParentCtrl
。
点击第二个链接就会发现this
和$scope
是不一样的,因为“函数调用时的作用域”是与ChildCtrl
关联的ChildCtrl
。 所以在这里, this
被设置为ChildCtrl
的$scope
。 在该方法中, $scope
仍然是ParentCtrl
的$ scope。
小提琴
我尽量不使用this
上$范围内定义的函数中,因为它变得扑朔迷离其中$范围受到影响,尤其是考虑到NG-重复,NG-包括NG-开关和指令都可以创建自己的子作用域。
'addPane'分配给这个的原因是因为<pane>
指令。
pane
指令确实require: '^tabs'
,它将tab控制器对象从父指令中放入链接函数中。
addPane
分配给this
以便pane
链接功能可以看到它。 然后在pane
链接函数中, addPane
只是tabs
控制器的一个属性,它只是tabsControllerObject.addPane。 因此,窗格指令的链接函数可以访问制表符控制器对象,因此可以访问addPane方法。
我希望我的解释清楚。这很难解释。
我刚刚阅读了关于两者之间差异的一个非常有趣的解释,并且越来越倾向于将模型附加到控制器,并且别名控制器将模型绑定到视图。 http://toddmotto.com/digging-into-angulars-controller-as-syntax/是文章。 他没有提到它,但是在定义指令时,如果您需要在多个指令之间共享某些内容并且不想要服务(有合法的情况下服务很麻烦),请将数据附加到父指令的控制器。 $ scope服务提供了很多有用的东西,$ watch是最明显的,但如果您只需要将数据绑定到视图,则使用模板中的普通控制器和'controller as'是很好的,并且可以说是可取的。
链接地址: http://www.djcxy.com/p/2181.html