如何将变量分配给函数内的别名控制器

How to assign variables to an aliased Controller inside a function?

本文关键字:别名 控制器 函数 变量 分配      更新时间:2023-09-26

免责声明:我真的不知道这个问题是否符合"问题"的Stackoverflow定义,因为我已经有了(不止)一个解决方案,我只是不喜欢我找到的解决方案。如果碰巧发生这种情况,我提前道歉,并欢迎其他选择。)

我正在创建一个Angularjs指令,我想使用Controller as ctrl语法,这样我就可以在HTML中使用ctrl.property,而不是非上下文的、可能有阴影的property

然而,这意味着,在Controller函数上,要在HTML中访问的变量需要绑定到this。例如:

<!-- HTML file: greetings.html -->
<ul>
  <li ng-repeat="item in main.items track by $index" ng-bind="item"></li>
</ul>
angular.module('GreetingModule').directive('greetings', function() {
  'use strict;'
  return {
    restrict: 'E',
    templateUrl: 'greetings.html',
    controller: function () {
      this.greetings = ['Hello', 'Hola', 'Salut'];
    },
    controllerAs: main
  }
});

我对此很满意。但当我开始使用函数时,事情就分崩离析了。

假设我需要加载服务中的问候语。

angular.module('GreetingModule').directive('greetings',
    ['langService', function(langService) {
  'use strict;'
  return {
    restrict: 'E',
    templateUrl: 'greetings.html',
    controller: function () {
      this.greetings = [];
      function languagesLoaded(langs) {
        for (var i = 0; i < langs.length; i++) {
          this.greetings.push(langs[i].greeting);
        }
      }
      langService.load({
        callback: languagesLoaded
      });
    },
    controllerAs: 'main'
  };
}]);

这将失败。回调时,调用languagesLoaded时,this未绑定,函数将抛出错误this.greetings is undefined

我已经找到了三种方法来解决这个问题,但我不喜欢这三种方法(我真的没有任何技术上的理由不喜欢它们,它们只是觉得错了,就像我试图做一些我不应该做的事情):

  1. 创建一个指向this的变量,并在函数中使用该变量:
    var self = this;
    // ...
    self.greetings.push(langs[i].greeting);
  1. 将对象参数中的this传递给langService.load()
    /* In the directive */
    langService.load({
      target: this,
      callback: languagesLoaded
    })
    /* In the service */
    function load(config) {
      // load languages, then:
      config.languagesLoaded.call(target, languages);
    }
  1. 将数组绑定到this和函数作用域,以便更改作用域变量也会影响this变量(因为它们引用相同的数组):
    var greetings = this.greetings = [];
    // ...
    greetings.push(langs[i].greeting);

还有别的办法吗?假设没有,以上哪种解决方案最正确?

您可以将函数的this绑定到控制器:

langService.load({
  callback: languagesLoaded.bind(this)
});

对于IE<9将需要polyfill,因为CCD_。

您的方法#1似乎是最好的。使用this时应该小心,因为它会根据上下文更改其含义,例如,就像在函数中一样。如果你使用的是第三方图书馆,有时你甚至不会知道这一点。

我觉得这本指南很有用。来自指南:

function Customer() {
    var vm = this;
    vm.name = {};
    vm.sendMessage = function() { };
}