角度变量指令名称

时间:2015-04-02 00:47:22

标签: angularjs

我确定以前曾经问过这个问题,但是很难提出问题,因此也难以搜索...

我的应用程序使用了一些第三方指令。目前,我正在弄乱的指令是xeditable lib中的指令,但这个问题并不仅仅是关于lib的问题,因为我之前遇到过这种需求。

目前,我的代码如下所示:

<div ng-switch on="editTypeNeeded">
    <div ng-switch-when="textarea" editable-textarea="myVar" onbeforesave="doBeforeSaveStuff($data)" class="whatever" ng-class="whatever2()" ng-mouseover="doStuff()" some-other-directive="doMoreStuff()">
        {{myvar}}
        ...
        and other stuff
    </div>
    <div ng-switch-when="textfield" editable-text="myVar" onbeforesave="doBeforeSaveStuff($data)" class="whatever" ng-class="whatever2()" ng-mouseover="doStuff()" some-other-directive="doMoreStuff()">
        {{myvar}}
        ...
        and other stuff
    </div>
    <div ng-switch-when="checkbox" editable-checkbox="myVar" onbeforesave="doBeforeSaveStuff($data)" class="whatever" ng-class="whatever2()" ng-mouseover="doStuff()" some-other-directive="doMoreStuff()">
        {{myvar}}
        ...
        and other stuff
    </div>
    <div ng-switch-when="date" editable-bsdate="myVar" onbeforesave="doBeforeSaveStuff($data)" class="whatever" ng-class="whatever2()" ng-mouseover="doStuff()" some-other-directive="doMoreStuff()">
        {{myvar}}
        ...
        and other stuff
    </div>
    ...
    etc...
</div>

当每个switch选项之间发生变化的事物为&#34; editable-textarea&#34;,&#34;可编辑时,代码重复的TON -text&#34;等

我想要的是用以下内容替换所有上述内容:

<div {{directiveName}}="myVar" onbeforesave="doBeforeSaveStuff($data)" class="whatever" ng-class="whatever2()" ng-mouseover="doStuff()" some-other-directive="doMoreStuff()">
    {{myvar}}
    ...
    and other stuff
</div>
显然,它不起作用,但必须有办法做这样的事情...


更新

我最终使用了所选答案,但稍作修改以允许变量指令名称和指令值。像这样:

.directive('useDirective', function ($compile) {
    return {
        restrict: 'A',
        link: function (scope, elem, attrs) {
            attrs.$observe('useDirective', function(directiveNameAndValue) {
                if (directiveNameAndValue) {
                    var nameAndValue = directiveNameAndValue.split('='),
                        dirName = nameAndValue[0],
                        value = nameAndValue[1] || '';
                    elem.attr(dirName, value);
                    elem.removeAttr('use-directive');
                    $compile(elem)(scope);
                }
            });
        }
    };
});

我这样使用它:

<div use-directive="{{getDirectiveType(value)}}=value" class="pointer" onbeforesave="notifyOfChange($data)">{{value}}</div>

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


更新2:
我发现上述技术似乎与angular-animate.js lib完美搭配。它导致lib多次出现以下错误:

 TypeError: Cannot read property 'parentNode' of undefined
     at angular-animate.js:1203
     at angular-animate.js:539
     at n.$digest (angular.js:14358)
     at n.$apply (angular.js:14571)
     at angular.js:16308
     at e (angular.js:4924)
     at angular.js:5312
但是,该页面似乎仍能正常工作。

1 个答案:

答案 0 :(得分:4)

你可以创建一个指令来统治它们:

<div lord-of-the-directives="{{directiveName}}">

这就像

module.directive('lordOfTheDirectives', function ($compile) {
  return {
    restrict: 'A',
    link: function (scope, elem, attrs) {
      attrs.$observe('lordOfTheDirectives', function(dirName) {
        if (dirName) {
          elem.append('<div ' + dirName + '>');
          $compile(elem)(scope);
        }
      });
    }
  };
});

(未经测试,但这是个想法)

在评论中按要求

更新,以保持元素不变(包含其类和内容):

module.directive('lordOfTheDirectives', function ($compile) {
  return {
    restrict: 'A',
    link: function (scope, elem, attrs) {
      attrs.$observe('lordOfTheDirectives', function (dirName) {
        if (dirName) {
          elem.attr(dirName, '');
          elem.removeAttr('lord-of-the-directives');
          $compile(elem)(scope);
        }
      });
    }
  };
});