ECMA6指令的动态控制器

时间:2016-03-17 18:14:35

标签: javascript angularjs angularjs-directive ecmascript-6

我试图使用name属性动态地将控制器设置为我的指令。到目前为止,这是我的代码。

HTML

<view-edit controller-name="vm.controller" view="home/views/med.search.results.detail.resources.audios.html" edit="home/views/med.media.resources.edit.html"></view-edit>

JS

export default class SearchResultsCtrl extends Pageable {

  /*@ngInject*/
  constructor($injector, $state, api) {

    super(
      {
        injector: $injector,
        endpoint: 'mediaMaterialsList',
        selectable:{
          itemKey: 'cid',
          enabled:true,
          params: $state.params
        },
        executeGet: false
      }
    );

    this.controller = SearchResultsResourcesAudiosCtrl;
  }
}

指令

export default class ViewEditDirective {

  constructor() {
    this.restrict = 'E';
    this.replace = true;
    this.templateUrl = 'home/views/med.view.edit.html';
    this.scope = {};
    this.controller = "@";
    this.name = "controllerName";
    this.bindToController = {
      'view': '@?',
      'edit': '@?'
    };

    this.open = false;
    this.controllerAs = 'ctrl';
  }
}

undefined获得vm.controller。我猜它在控制器可以将控制器分配给变量之前进行渲染(我对它进行了重组,并且它将控制器设置在变量中)。

我按照这个答案来实现这个目标,但到目前为止还没有运气。 How to set the dynamic controller for directives?

感谢。

1 个答案:

答案 0 :(得分:1)

问题与ES6(ES5上的糖语法涂层)无关,这就是Angular范围生命周期的工作原理。

该指令可能显示属性插值的处理方法

// <div ng-init="a = 1"><div sum="{{ a + 1 }}"></div></div>
app.directive('sum', function () {
  return {
    scope: {},
    controller: function ($attrs) {
      console.log($attrs.sum) // {{ a + 1 }}
      // ...
    },
    link: function (scope, element, attrs) {
      console.log(attrs.sum) // 2
    }
  };
});

如果$attrs.sum之后设置了2值,则link可能仍然不是a(即在父指令link中)。

假设一个范围上的值可以根据某个时间点的另一个范围的值计算,这是不安全的(并且本身是错误的)。因为它可能不是。这就是观察者和数据绑定的原因。

所有controller: '@'魔法值都会获得uninterpolated attribute value并将其用作控制器名称。所以不,它不会从vm.controller插入控制器名称,并使用'vm.controller'字符串作为控制器名称。

允许动态设置其控制器的指令示例可能类似于

// dynamic-controller="{{ ctrlNameVariable }}"
app.directive('dynamicController', function () {
    return {
        restrict: 'A',
        priority: 2500,
        controller: function ($scope, $element, $attrs, $interpolate, $compile) {
            var ctrlName = $interpolate($attrs.dynamicController)($scope);

            setController(ctrlName);
            $attrs.$observe('dynamicController', setController);

            function setController (ctrlName) {
                if (!ctrlName || $attrs.ngController === ctrlName) {
                    return;
                }

                $attrs.$set('ngController', ctrlName);
                $compile($element)($scope);
            }
        }
    };
});

具有重新编译可能带来的所有副作用。