2015-04-02 3 views
2

Я уверен, что это было предложено раньше, но это своего рода трудно поставить в вопрос, и, следовательно, также трудно найти ...имя переменной директивы в угловом

Кусок моего приложения использует одну из нескольких сторонних директив. Директивы, с которыми я возился, на данный момент находятся в библиотеке xeditable, но этот вопрос касается не только этой библиотеки, как и раньше.

Мой код, на данный момент, выглядит примерно так:

<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> 

Это TON дублирования кода, когда только вещь, которая изменяется между каждым switch опции «редактируемые-текстовое поле», «editable- текст»и т.д.

то, что я хотел бы, чтобы заменить все выше с чем-то вроде этого:

<div {{directiveName}}="myVar" onbeforesave="doBeforeSaveStuff($data)" class="whatever" ng-class="whatever2()" ng-mouseover="doStuff()" some-other-directive="doMoreStuff()"> 
    {{myvar}} 
    ... 
    and other stuff 
</div> 

, которые, очевидно, не работает, но там должен быть способ сделать что-то подобное ...


Update:

Я закончил с использованием выбранного ответа, но с небольшой модификацией, чтобы разрешить как переменное имя директивы, так и директивное значение. Как так:

.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


Update 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

Напиши свою собственную директиву, которая воплощает в себе все вышеперечисленную логику? – link64

+0

Я не понимаю, почему вы не могли вставить эту логику коммутатора в шаблон директивы, а затем просто передать или установить атрибут в директиве для editTypeNeed.Сохраните HTML-код внутри директивы и просто используйте директиву в своей форме, чтобы сохранить чистоту. –

ответ

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

(не проверял, но это идея)

Update по запросу в комментарии, сохранить элемент как есть (с его классами и т. д.):

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

Мне нравится идея ... Есть ли способ сделать эту работу, когда ваш div имеет кучу других attrs и выглядит более как это: '

{{myVar}}
'? Или идея о том, что 'lordOfTheDirectives' не принимает никаких attrs, и все дополнительные attrs/директивы должны быть добавлены из' lordOfTheDirectives', а не * переданы * в него? – Troy

+2

Да, вместо * добавления * новой директивы вы можете добавить свое имя непосредственно к элементу и перекомпилировать все это. Я обновил свой ответ этим методом. Обратите внимание, что я удаляю директиву лорда, чтобы оба актива не возились друг с другом: они становятся одноразовой директивой. Если это не то, что вы хотите, вы можете сохранить атрибут 'lord-of-the-dirctives' и удалить предыдущую директиву перед добавлением нового. – floribon

Смежные вопросы