向 angularjs 指令添加和编译属性

Add and compile attributes to angularjs directive

本文关键字:编译 属性 添加 angularjs 指令      更新时间:2023-09-26

我有一个指令<my-dir></my-dir>,该指令应始终具有通过角度属性提供的特定功能:<my-dir ng-show="ctrl.shown"></my-dir> .这里 ctrl 是通过指令定义controllerAs: 'ctrl'定义的控制器。

我想通过在编译指令时自动添加属性来简化此指令并避免错误。这样其他用户只需键入 <my-dir> .向指令添加属性很简单,但这些新属性似乎没有被编译。

app.directive("myDir", function() {
  console.log('myDir');
  return {
    restrict: 'E',
    controller: 'DirectiveController',
    controllerAs: 'ctrl',
    template: '<span>Controller Content</span>'
    // Attempt to attach the 'ng-show' attribute to the element
    link: function($scope, $element, attrs) {
      $element.attr('ng-show', 'ctrl.shown');
    }
  };
});

我尝试了很多不同的事情:在link:中添加属性,在compile:中添加属性,甚至在添加属性后使用$compile($element[0]['my-dir'])($scope)

示例 plnkr:http://plnkr.co/edit/PREavAIn1vqUdZYLsypt?p=preview

使用ctrl.shown的 plnkr 示例:http://plnkr.co/edit/dTWIzClZG4YpE76AMCWk?p=preview

更新

因此,将此逻辑放入指令的编译步骤似乎是正确的方向:

...
compile: function(tElem, tAttrs) {
  // appears that you need to remove this attribute  
  // to stop the directive from looping infinitely 
  // through the compile step
  tElem.removeAttr('my-dir'); 
  tElem.attr('ng-hide', 'true');
  return function(scope) {
    $compile(tElem)(scope);
  }
}

以下是更新的 plnkr: http://plnkr.co/edit/uyfJl8b1w5esYGv7SIsx?p=preview

看到这个问题

OP 的解决方案

根据Paul Trone对这个话题的回答,我想出了一个适合我的解决方案。

基本上,我在添加角度属性后重新编译元素。为了避免无限循环,我还使用自定义标记标记元素,并在标记元素时停止编译。

这样,我可以多次部署<my-dir></my-dir>,每次在指令的根级别使用隐式自定义功能。这样就可以使用 ng-show 来隐藏整个指令,而不仅仅是其中的模板化元素。

angular.module('app', []);
angular.module('app').directive("myDir", function($compile) {
  return {
    restrict: 'E',                     // I prefer this directive to be Element-only
    controller: 'DirectiveController',
    controllerAs: 'ctrl',
    template: '<span>Controller Content</span>',
    /**
     * Add the necessary angular attributes
     *   along with a 'compiled' attribute as tag
     *   such that the element doesn't infinitely compile itself
     *
     * This still allows multiple of the same directive to be
     *   compiled at the same time
     */
    compile: function(tElem, tAttrs){
      // Check if the element has been tagged
      if(! tAttrs['compiled']) {
        // Tag the element so it doesn't compile again
        tElem.attr('compiled', true)
        // Add custom angular attributes
        tElem.attr('ng-show', 'ctrl.shown');
        // Recompile
        return function(scope) { $compile(tElem)(scope); };
      }
    }
  };
});
angular.module('app').controller("DirectiveController", function() {
    var shown = false;
});

例 : http://plnkr.co/edit/wbs0vcFmz15oL2twm6AC?p=preview

或者,可以将

观察程序附加到一个变量,该变量将类模拟切换到ng-show的工作方式,但这将开始复制ng-show属性预期的确切功能。

不确定我是否理解您要正确执行的操作,但是您为什么不像这样将属性添加到模板中呢?

template: '<span ng-show="ctrl.shown">Controller Content</span>'