如何在指令定义期间将新指令正确添加到指令中

How to properly add new directives to a directive during its definition

本文关键字:指令 添加 新指令 定义      更新时间:2023-09-26

我在angularjs中的动态指令遇到了一个主要问题。

我试图通过一个对象在指令定义过程中添加新指令:

compile: function () {
    return {
      pre: function (scope, iElement, iAttrs) {
        // in this case cbAttrs is an object {cbSuggest: true, cbDatepicker: true}, for example
        scope.objects = JSON.parse(iAttrs.cbAttrs);
        if (!iAttrs.compiled) {
          angular.forEach(scope.objects, function(props) {
            for (var prop in props) {
              iAttrs.$set(prop, (typeof props[prop] === 'object' ? JSON.stringify(props[prop]) : props[prop]));
            }
          });
          iAttrs.$set('dataCompiled', true);
          $compile(iElement)(scope);
        }
      }
    };
  }

我已经设法使它以这种方式工作。但老实说,我真的觉得这不是正确的做法,我不明白为什么我必须在指令的PRE编译阶段编译元素。

如果我以这种方式添加,输入的行为会很奇怪,例如:试图在输入中向左移动,然后删除一个字母,会使光标向右移动到输入的末尾。

我在链接函数中尝试过,它会为输入生成相同的行为:

link: function(scope, elem, attrs) {
  scope.objects = JSON.parse(attrs.cbAttrs);
    if (!attrs.compiled) {
      angular.forEach(scope.objects, function(props) {
        for (var prop in props) {
          attrs.$set(prop, (typeof props[prop] === 'object' ? JSON.stringify(props[prop]) : props[prop]));
        }
      });
      attrs.$set('dataCompiled', true);
      $compile(elem)(scope);
    }
  }

老实说,我不知道还能做什么。我已经看到了模板示例的注释,但我不想将return元素设置为硬编码。

同时存在两个问题的Plunker:http://plnkr.co/edit/tbQubTMarjxB8ogzhtey?p=previewjsFiddle:http://jsfiddle.net/plantface/Lwktcyu7/

这就是我解决所有问题的方法:

return {
  restrict: 'A',
  terminal: true,
  priority: 1000,
  compile: function () {
    return {
      post: function (scope, iElement, iAttrs) {
        var attrs = $interpolate(iAttrs.cbAttrs);
        attrs = JSON.parse(scope.$eval(attrs));
        angular.forEach(attrs, function(attr){
          for(var prop in attr) {
            iElement.attr(prop, (typeof attr[prop] === 'object' ? JSON.stringify(attr[prop]) : attr[prop]));
          }
        });
        iElement.removeAttr('data-cb-attrs');
        $compile(iElement)(scope);
      }
    };
  }
};

基本上,我使用terminal来阻止所有编译继续运行,添加我需要的属性,然后删除directive属性并编译它。