当我的指令控制器 运行 使用 "Controller As" 语法时未评估数据

Data not evaluated when my directive controller run using "Controller As" syntax

我创建了一个简单的 Angular JS 指令:

这里是指令代码

(function() {

'use strict';

  angular
    .module('main')
    .directive('myDirective', myDirective);

  /** @ngInject */
  function myDirective() {
    return {
      bindToController: true,
      controller: MyController,
      controllerAs: 'vm',
      restrict: 'E',
      scope: {
        number: '<'
      },
      templateUrl: 'my-directive.template.html',
    };
  }

  /** @ngInject */
  function MyController($scope, $timeout) {
    var vm = this;

    // calculate(); // previous and next = NaN
    // $timeout(calculate, 1); // Works
    vm.watch = $scope.$watch('vm.number', calculate); //Works

    function calculate() {
      vm.previous = vm.number - 1;
      vm.next = vm.number + 1;
      vm.watch();
    }
  }
})();

我是这样称呼它的

<my-directive number="7"></my-directive>

我的问题是:

经过研究,我找到了 2 个解决方案,但它们看起来不太好:

  1. 在 MyController
  2. 中使用 $timeout 服务
  3. 在 MyController
  4. 中使用 $scope.$watch 服务

我认为如果评估数据需要更长的时间,解决方案(1)有时可能会下降。

由于不需要看数据,采用方案(2)我在函数calculate执行完后就把watch去掉了,但是这里用watch感觉不对


那么,有更好的解决方案吗?或者解决方案 (2) 就可以了?

问题出在你的模块声明中。

这个

angular
.module('main')

应该是这个

angular
.module('main', [])

声明新模块时需要[requires]参数。

正如用户 Claies 所建议的那样,我为此创建了一个组件,并且效果很好。

这里是组件声明

(function() {
  'use strict';

  angular
    .module('main')
    .component('myComponent', {
      templateUrl: 'my-component.template.html',
      controller: MyController,
      controllerAs: 'vm',
      bindings: {
        number: '<',
        goNext: '&',
        goPrevious: '&'
      }
    });

  /** @ngInject */
  function MyController() {
    var vm = this;

    vm.$onInit = onInit;
    vm.$onChanges = onNumberChange;

    vm.onNext = onNext;
    vm.onPrevious = onPrevious;

    function onInit() {
      calculate();
    }

    function onNumberChange(changesObj) {
      if (changesObj.number) {
        calculate();
      }
    }

    function onNext() {
      vm.goNext();
    }

    function onPrevious() {
      vm.goPrevious();
    }

    function calculate() {
      vm.previous = vm.number - 1;
      vm.next = vm.number + 1;
    }

  }
})();

为了测试组件的 $onChanges 功能,我添加了一个 add 和一个 subtract 操作。

下面是我在 HTML 页面中使用该组件的方式

<my-component number="vm.number" go-next="vm.goNext()" go-previous="vm.goPrevious()"></my-component>

我做的完整例子可以在这个Plunker

中找到