2013-05-10 2 views
28

У меня есть директива myDirective с переменным типом. Если я запустил <my-directive type="X"> Я хочу, чтобы директива использовала templateUrl: x-template.html. Если я делаю <my-directive type="Y"> Я хочу, чтобы директива использовала templateUrl: y-template.html.Угловая директива Различные шаблоны

Это моя текущая директива.

app.directive('myDirective', function() { 
    var myDirective = { 
     templateUrl: 'X-template.html', 
     restrict: 'E', 
     scope: { 
      type: '=' 
     }, 
    }; 
    return myDirective; 
}); 

Я прочитал через stackoverflow и угловую документацию, но не нашел ничего, что мне нужно.

Я сейчас пытаюсь сделать что-то вдоль линий:

if ($scope.type === 'X') { 
    templateUrl: 'X-template.html', 
} 
else if ($scope.type === 'Y') { 
    templateUrl: 'Y-template.html', 
} 

Но не знаю, где это делать.

Вы, ребята, знаете, возможно ли это и как?

+0

Опубликовать директиву пожалуйста. – GFoley83

+0

Обновлен вопрос, спасибо. –

+0

Возможно, попробуйте 'type: '&'' вместо 'type: '='' и 'templateURL: '{{type}} - template.html','. Его длинный выстрел, и я его не тестировал, я просто размышляю. Кроме того, укажите свой шаблон 'templateURL' после оператора области. Не знаю, нужен ли вам тоже, это просто заставляет меня чувствовать себя тепло внутри ... – WebWanderer

ответ

25

Вы можете работать вокруг this issue используя ng-includecompile внутри:

app.directive('myDirective', function() { 
    return { 
     restrict: 'E', 
     compile: function(element, attrs) { 
      element.append('<div ng-include="\'' + attrs.type + '-template.html\'"></div>'); 
     } 
    } 
}); 

fiddle

+0

спасибо, что сработало. –

+0

@MarkRajcok Как я могу передать значение шаблонам? предположим, если я хочу установить атрибут name = "something" и передать эти значения в шаблоне ?? – anam

6

Если вы готовы жить на переднем крае с билда на пути 1.1.x кода (обратите внимание на предупреждение, прикрепленное к каждой записи заметок 1.1.x, поэтому я не разбавляю этот ответ, повторяя его снова здесь), вам повезло - эта функция была добавлена ​​только в выпуске 1.1.4 3 апреля. Вы можете найти примечания к выпуску для версии 1.1.4 here, а функция task log включает тест Jasmine, который демонстрирует, как использовать новую функциональность.

Если вы более консервативны и используете версию 1.0.x, то вы не сможете выполнить это так же легко, но это можно сделать. Решение Марка Rajcok выглядит, как он будет соответствовать вашим требованиям, как заявил, но я бы просто добавить несколько дополнительных заметок:

  • Помимо своего выпуска 1.1.4, во время компиляции директивы не поддерживают изменения во время выполнения.
  • Вы можете рассмотреть replaceWith() вместо append() поскольку <my-directive> не является стандартным определенным типом HTML элемента.
  • Если ваши шаблоны X и Y содержат дополнительные директивы, я не думаю, что вы сможете легко передавать атрибуты на <my-template> до корневого элемента вашего шаблона.
    • Директива с заменой: true передаст атрибуты из исходного элемента в свой корень замены, но я не думаю, что ngInclude будет делать то же самое с хоста на корень включенного шаблона.
    • Я также напоминаю, что ngInclude не требует, чтобы его шаблон имел ровно один корневой элемент.
    • Возможно, вы сохранили атрибуты для родителя-замены, используя replaceWith() вместо append() и обернув тег <div ng-include=""> в пределах <div></div>.Внешний <div> может содержать атрибуты и все равно будет доступен после того, как элемент <div ngInclude> заменит себя загруженным контентом.
  • Следует иметь в виду, что ngInclude создает новую область действия. Это подводит вас к мигающему желтому знаку клаксонов об опасностях примитивных моделей. Для получения дополнительной информации см. this fine page from Angular's GitHub depot.

Я могу предложить другую альтернативу для версии 1.0.x, но она включает в себя достаточное количество кода. Это более тяжелая операция, но у нее есть потенциал не только для переключения между шаблонами, но и с полнофункциональными директивами. Более того, его поведение более динамично.

app.directive('myDirective', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     templateUrl: 'partials/directive/my-directive.html', 
     link: function(scope, element, attrs, ctrl) { 
      // You can do this with isolated scope as well of course. 
      scope.type = attrs.type; 
     } 
    } 
); 

мои-directive.js

<div ng-switch on="{{type}}"> 
    <div ng-switch-where="X" ng-include="X-template.html"></div> 
    <div ng-switch-where="Y" ng-include="Y-template.html"></div> 
</div> 

мой-directive.html

+0

спасибо за отличное завершение! – powtac

+0

Я бы предпочел, чтобы templateURL взял массив! – sidonaldson

4

Я решить эту проблему так:

app.directive("post", function ($templateCache, $compile) { 
function getTemplate(mode) { 
    switch (mode) { 
     case "create": 
      return "createPost.html"; 
     case "view": 
      return "viewPost.html"; 
     case "delete": 
      return "deletePost.html"; 
    } 
} 

var defaultMode = "view"; 

return { 
    scope: {}, 
    restrict: "AE", 
    compile: function (elem, attrs, transclude) { 
     return function ($scope, $element, $attr) { 
      function updateTemplate() { 
       $element.html(""); 
       $compile($templateCache.get(getTemplate($scope.mode)).trim())($scope, function (clonedElement, scope) { 
        clonedElement.appendTo($element); 

       }); 
      } 

      $scope.mode = $attr.mode || defaultMode; 

      $scope.$watch("mode", updateTemplate); 
     } 
    } 
} 
}); 

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

+0

может у вас поделитесь скрипкой ??? – anam

+0

Что случилось с этим? – trickpatty

101

Угловая принимает функцию в качестве опции шаблона, так что вы могли бы сделать что-то вроде этого:

.directive('myDirective', function() { 
    return { 
     templateUrl: function (tElement, tAttrs) { 
      if (tAttrs) { 
       if (tAttrs.type === 'X') { 
        return 'X-template.html'; 
       } 
       if (tAttrs.type === 'Y') { 
        return 'Y-template.html'; 
       } 
      } 
     } 
    } 
}); 

Для получения дополнительной информации обратитесь к документации по $compile службы.

+10

Это самый краткий ответ, должен быть принят. –

+0

Спасибо. Это и есть. –

-1

Хорошо, это может помочь кому-то здесь :-)

Чтобы придать свой собственный Attr в вашу ссылку или контроллер функции использовать следующее.

я на работе прямо сейчас, но будет размещать скрипку позже, если я получу шанс :-)

.directive('yourDirective', function() { 
    return { 
    restrict: 'EA', 
    template: '<div></div>', // or use templateUrl with/without function 
    scope: { 
     myAttibute: '@myAttr' // adds myAttribute to the scope 
    }, 
    link: function(scope) { 
     console.log(scope.myAttibute); 
    } 
    } 
} 

// HTML ""

// Console выведет "Foo"

4

Это моя версия для возможного переопределения шаблона по умолчанию

templateUrl: function (elem, attrs) { 
    if (attrs.customTemplate) { 
    return '/path/to/components/tmpl/' + attrs.customTemplate + '.html'; 
    } else { 
    return '/path/to/components/tmpl/directive.html'; 
    } 
} 

, например, на директиве

<div my-directive custom-template="custom"></div> 
+0

Это сработало для меня, спасибо! –

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