解决方法

"How does this and $scope work in AngularJS controllers?"

简短回答:

  • this
    • When the controller constructor function is called, this is the controller.
    • When a function defined on a $scope object is called, this is the "scope in effect when the function was called". This may (or may not!) be the $scope that the function is defined on. So, inside the function, this and $scope may not be the same.
  • $scope
    • Every controller has an associated $scope object.
    • A controller (constructor) function is responsible for setting model properties and functions/behaviour on its associated $scope.
    • Only methods defined on this $scope object (and parent scope objects, if prototypical inheritance is in play) are accessible from the HTML/view. E.g., from ng-click, filters, etc.

长答案:

控制器函数是JavaScript构造函数.当构造函数执行时(例如,当视图加载时),将(即"函数上下文")设置为控制器对象.所以在"tabs"控制器构造函数中,当addPane函数创建时

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

它是在控制器对象上创建的,而不是在$ scope上创建的.视图看不到addPane函数 - 它们只能访问在$ scope上定义的函数.换句话说,在HTML中,这将不起作用:

<a ng-click="addPane(newPane)">won't work</a>

在"tabs"控制器构造函数执行后,我们有以下:

在制表符控制器构造函数之后

黑色虚线表示原型继承 - 隔离范围从原型继承自范围. (它不从原型继承自HTML中遇到指令的有效范围.)

现在,pane指令的链接函数想要与tabs指令进行通信(这实际上意味着它需要影响标签以某种方式隔离$ scope).可以使用事件,但另一种机制是使用pane指令 require tabs控制器. (似乎没有机制用于 require tabs $ scope.)

所以,这提出了一个问题:如果我们只能访问tabs控制器,我们如何访问的选项卡隔离$范围(这是我们真正想要的)?

嗯,红色的虚线是答案. addPane()函数的”scope”(我指的是JavaScript的函数作用域/ closures这里)给了函数访问tabs $ scope.也就是说,addPane()可以访问上图中的”tabs IsolateScope”,因为定义了addPane()时创建了一个闭包. (如果我们在tabs $ scope对象上定义addPane(),则pane指令将无法访问此函数,因此它将无法与tabs $ scope进行通信.)

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

在$ scope上定义的函数中,设置为"$ scope in effect /调用函数时的效果.假设我们有以下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上定义的函数中使用 this ,因为它会影响到$ scope的影响,特别是考虑到ng-repeat,ng-include,ng-switch ,并且指令都可以创建自己的子范围.




相关问题推荐