"this" vs $scope在AngularJS控制器中的使用

45 浏览
0 Comments

"this" vs $scope在AngularJS控制器中的使用

在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,代码就会中断。

文档说明实际上存在差异,但没有说明差异是什么:

以前版本的Angular(1.0 RC之前)允许您将this与$scope方法交替使用,但现在不再是这种情况。在作用域中定义的方法内,this和$scope是可互换的(angular将this设置为$scope),但其他情况下在您的控制器构造函数中不是这样。

this和$scope在AngularJS控制器中如何工作呢?

admin 更改状态以发布 2023年5月22日
0
0 Comments

\"addPane\"被分配给这个变量,原因是因为有指令。\n指令会require: \'^tabs\',这样就可以将来自父指令的tabs控制器对象放入链接函数中。\n将addPane分配给this,以便链接函数可以看到它。然后在链接函数中,addPane只是tabs控制器的一个属性,就是tabsControllerObject.addPane。因此,pane指令的链接函数可以访问tabs控制器对象,从而访问addPane方法。\n我希望我的解释足够清楚,这有点难以解释。

0
0 Comments

“AngularJS控制器中的this$scope是如何工作的?”

简短回答

  • this
    • 当调用控制器构造函数时,this指代的是控制器本身。
    • 当调用一个在$scope对象上定义的函数时,this指代的是“调用该函数时所生效的作用域”。这可能(或可能不)是该函数所在的$scope对象。因此,在函数内部,this$scope不一定相同。
  • $scope
    • 每个控制器都有一个关联的$scope对象。
    • 控制器(构造函数)负责在其关联的$scope对象上设置模型属性、函数/行为。
    • 只有在此$scope对象(和可能存在的父作用域对象,如果使用原型继承)上定义的方法可以从HTML/视图中访问。例如,从ng-click、过滤器等。

长答案

控制器函数是一个JavaScript构造函数。当构造函数执行时(例如,当视图加载时),this(即“函数上下文”)被设置为控制器对象。因此,在“标签页”控制器构造函数中创建addPane函数时

this.addPane = function(pane) { ... }

它是在控制器对象上创建的,而不是在$scope对象上创建的。视图无法看到addPane函数——它们只能访问在$scope上定义的函数。换句话说,在HTML中,这是行不通的:

won't work

在“标签页”控制器构造函数执行后,我们有以下内容:

after tabs controller constructor function

虚线黑线表示原型继承——独立作用域原型继承自Scope。(它不是从HTML中遇到的作用域原型继承。)

现在,面板指令的link函数想要与标签指令通信(这实际上意味着它需要以某种方式影响标签独立$scope)。事件可以使用,但另一种机制是让面板指令require标签控制器。(似乎没有机制让面板指令require标签$scope。)

所以,这就有一个问题:如果我们只能访问标签控制器,那么如何访问标签独立$scope(这是我们真正想要的)?

好吧,红色虚线就是答案。添加Pane()函数的“作用域”(我指的是JavaScript中的函数作用域/闭包)给该函数访问标签独立$scope。也就是说,addPane()可以访问上面这个图中的“标签IsolateScope”,因为在定义addPane()时创建了一个闭包。(如果我们将addPane()定义在标签$scope对象上,面板指令将无法访问该函数,因此它将无法与标签$scope进行通信。)

回答你的问题的另一部分:控制器中的$scope是如何工作的?

在$scope中定义函数时,this被设置为“函数调用时/处生效的$scope”。假设我们有以下HTML代码:

   log "this" and $scope - parent scope
      log "this" and $scope - child scope


并且ParentCtrl(仅)有:

$scope.logThisAndScope = function() {
    console.log(this, $scope)
}


点击第一个链接将显示this$scope是相同的,因为“函数调用时生效的$scope”是与ParentCtrl相关联的$scope。
点击第二个链接将显示this$scope不相同,因为“函数调用时/处生效的$scope”是与ChildCtrl相关联的$scope。因此,在这里,this被设置为ChildCtrl$scope。 在方法中,$scope仍然是ParentCtrl的$scope。
我尝试不在$scope中定义函数时使用this,因为这会使得哪个$scope被影响变得混乱,特别是考虑到ng-repeat、ng-include、ng-switch和指令都可以创建它们自己的子作用域。

0