从命名/未命名的控制器引用Angular控制器成员

时间:2013-12-08 22:09:16

标签: javascript angularjs angularjs-scope angular-ui-router

我决定提出这个问题,因为我对 Angular 以及 JavaScript 的更精细部分的工作方式感到非常困惑。我试着制定我的问题,以便可以分解。

  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,所以{{1} }。

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

    {{ctrl.otherValue}}

    现在再次如上所述,我使用.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

    第2点摘要:当我不使用controllerAs语法时,我只能调用我习惯的<button ng-click="ctrl.otherFunc()"> 函数,并且只能调用$scope.我引用命名控制器时的函数。 这与 point 1 形成鲜明对比,我可以从命名或未命名的控制器定义中引用this.变量。

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

    我也认为这些行为与 ui-router 无关,但它通常是如何运作的,所以我也想知道:

    • $scope应该设置什么,不应该设置什么?
    • 应该在函数本身(?)上设置什么,不应该设置什么?
    • 使用命名控制器时有没有办法访问$scope函数?
    • 我缺少任何建议或一些明显的观点?

    感谢您提前抽出时间。

1 个答案:

答案 0 :(得分:1)

$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对象的成员,而不是控制器,因此无法以{{{{{{ 1}}。

  

我缺少任何建议或一些明显的观点?

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