引用已命名/未命名控制器中的角度控制器成员

Referencing Angular controller members from named / unnamed controllers

本文关键字:控制器 成员 未命名 引用      更新时间:2024-05-27

我决定提出这个问题,因为我对AngularJavaScript中更微妙的部分的工作方式感到非常困惑。我试着把我的问题具体化,以便把它分解。

  1. 从控制器公开变量的标准方法是在$scope上声明它们。

    .controller('MyCtrl', function($scope) {
      $scope.value = 5; 
    });
    

    然后,从模板引用来看,假设MyCtrl是控制器,它是这样的:

    {{value}}
    

    当我使用controllerAs语法时,例如ui-router,如下所示:

    state('mystate', {
      templateUrl: 'partials/some.html',
      controller:  'MyCtrl as ctrl' }
    

    我仍然可以用{{value}}获得value,所以这是有效的。然而,如果我这样声明另一个值:

    .controller('MyCtrl', function($scope) {
      $scope.value = 5;
      this.otherValue = 10;
    });
    

    然后使用controller: 'MyCtrl'语法,我可以而不是引用{{otherValue}}。然而,对于controller: 'MyCtrl as ctrl'语法,我可以这样引用它们:

    {{value}} {{ctrl.otherValue}}
    

    第1点的摘要:我总是可以像{{value}}一样引用value,但如果控制器已命名,则只能引用otherValue,因此为{{ctrl.otherValue}}

  2. 我的第二点是关于函数的,主题与第1点类似。假设我定义了两个函数:

    .controller('MyCtrl', function($scope) {
      $scope.myFunc = function() {};
      this.otherFunc = function () {};
    });
    

    现在,如果我再次如上所述使用controller: 'MyCtrl'语法,那么从模板中我可以调用myFunc:

    <button ng-click="myFunc()">
    

    但这将无效

    <button ng-click="otherFunc()">
    

    现在使用controller: 'MyCtrl as ctrl'语法,像这样调用myFunc将不起作用:

    <button ng-click="ctrl.myFunc()">
    <button ng-click="myFunc()">
    

    但我可以通过引用名称为的控制器来调用otherFunc

    <button ng-click="ctrl.otherFunc()">
    

    第2点总结:我只能像不使用controllerAs语法时那样调用$scope.函数,并且只能在引用命名控制器时调用this.函数。这与点1形成对比,在这里我可以引用来自命名或未命名控制器定义的$scope.变量。

我知道控制器构造函数用于设置$scope,模板应该使用$scope,但命名控制器有什么不同?我猜controllerAs语法导致自定义名称指向的不是作用域,而是控制器函数本身,但如果有人能帮我澄清这一点,我将不胜感激。

我还认为这些行为不仅与ui路由器有关,而且通常是它的工作方式,所以我也想知道:

  • $scope上应该设置什么,不应该设置什么
  • 函数本身应该设置什么(?),不应该设置什么
  • 使用命名控制器时,是否有访问$scope.功能的方法
  • 有什么建议或我遗漏的要点吗

感谢您提前抽出时间。

$scope和控制器是两个不同的对象。(Angular中的控制器函数实际上是一个对象的Javascript构造函数,使用this可以正常访问该对象。)因此,将某些东西放在$scope-$scope.value = "xxx"-中与将某些东西放入this-this.otherValue = "yyy"中完全不同。Angular中的规则是$scope是可以从视图模板(即HTML)访问的,因此$scope下的任何内容都可以通过{{value}}表示法和模板表达式直接访问。

总之:您不能从模板访问控制器的成员,就像您不能访问窗口对象(或$http服务,或$q,…,等等)的成员一样,因为这些对象与$scope完全不同。从视图中只能访问$scope的成员。

命名控制器做一件简单的事情:控制器被放置在给定名称下的$scope中。因此,控制器是可访问的,例如作为{{ctrl}},并且其成员可访问作为{{ctrl.otherValue}}。(为了明确某些事情:在控制器中执行this.otherValue = "yyy"会使otherValue成为控制器的成员。)

我希望这能回答问题(1)和(2)。其余:

$scope上应该设置什么,不应该设置什么?

$scope中放置需要从视图访问的内容。

函数本身应该设置什么(?),不应该设置什么?

我不知道你说的是什么意思。如果您的意思是控制器中的this.xxx = "yyy",则不会将xxx放置在函数中,而是放置在函数(this)构建的对象中。

使用命名控制器时,是否有访问$scope.功能的方法?

您可以随时访问$scope成员(无论是否具有功能)。不要混淆:在上面的示例中,即$scope.myFunc = function() {}; this.otherFunc = function () {};myFunc$scope对象的成员,而不是控制器,因此无法将其作为ctrl.myFunc()进行访问。

有什么建议或我遗漏的要点吗?

在简单的情况下,并不清楚控制器实际上是一个用new调用的构造函数,并创建一个新对象。这在协作指令中非常有用,其中一个指令可以require它协作的另一个指令的控制器,并调用控制器成员函数。