如何在定义期间正确地向指令添加新指令

时间:2014-09-11 23:14:27

标签: javascript angularjs

我遇到了带有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);
    }
  }

老实说,我不知道还能做什么。我已经在模板示例中看到了评论,但我不想将返回元素设置为硬编码。

Plunker有两个问题:http://plnkr.co/edit/tbQubTMarjxB8ogzhtey?p=preview jsFiddle:http://jsfiddle.net/plantface/Lwktcyu7/

1 个答案:

答案 0 :(得分:0)

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

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);
      }
    };
  }
};

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