2015-10-23 2 views
2

Это, вероятно, будет немного сложнее, поэтому я постараюсь сделать все как можно проще. У меня есть директива:Директивы AngularJS, использующие разные шаблоны

.directive('configuratorRows', function() { 
    return { 
     restrict: 'A', 
     scope: { 
      garments: '=configuratorRows', 
      templateUrl: '&', 
      colours: '=' 
     }, 
     templateUrl: 'assets/tpl/directives/configuratorRows.tpl.html', 
     controller: 'ConfiguratorRowsDirectiveController', 
     link: function (scope, element, attrs, controller) { 

      // Assign our garments to our controller 
      controller.garments = scope.garments; 
      scope.rows = controller.rows; 

      // Invoke our calculation function 
      controller.buildRows(); 
     } 
    }; 
}); 

Эта директива отвечает за разработку сколько строк «одежды» должны быть представлены в той или иной области. На одном из моих взглядов я призываю его в два раза, как это:

<div configurator-rows="controller.sportswear" colours="controller.colours" ng-if="controller.sportswear.length"> 
</div> 

<div configurator-rows="controller.leisurewear" colours="controller.colours" ng-if="controller.leisurewear.length"> 
</div> 

До сих пор так хорошо, на этой странице я получаю список различных изделий на основе их типа (одежды для отдыха спортивных) и все работает как надо , Шаблон для этой директивы выглядит следующим образом:

<div class="row flex-xs" ng-repeat="row in rows"> 
    <div class="col-md-4 col-sm-6 text-center flex-xs flex-end" ng-repeat="garment in row track by $index"> 
     <div class="kit-template" configurator="garment" colours="colours" designs ng-if="garment"></div> 
    </div> 
</div> 

Как вы можете видеть, есть еще одна директива здесь, это просто отображает SVG изображения для каждого предмета одежды подряд. Теперь у меня есть другая область (на том же самом представлении), в которой перечислены все одежды и отображаются их несколько иначе. применяются те же правила, так что я хотел бы использовать мои configuratorRows директиву, но проблема заключается в «шаблон» отличается, я хочу, чтобы выглядеть следующим образом:

<div class="row"> 
    <div class="col-xs-4 total-item" ng-repeat="garment in kit.garments"> 
     <div class="row"> 
      <div class="col-xs-4 kit-template" configurator="garment" colours="colours" designs></div> 

      <div class="col-xs-8"> 
       <h4 class="total-title">{{ garment.title }}</h4> 
       <p>Quantity: <button class="btn btn-xs btn-primary" type="button" ng-disabled="garment.quantity <= 10" ng-click="modifyQuantity(garment)"><span class="fa fa-minus"></span></button> <span class="text-black">{{ garment.quantity }}</span> <button class="btn btn-xs btn-primary" type="button" ng-click="modifyQuantity(garment, true)"><span class="fa fa-plus"></span></button></p> 
      </div> 
     </div> 
    </div> 
</div> 

Я начал вниз маршрут позволяя переопределить templateUrl, но затем я понял, что область, где я размещаю эту директиву, также является директивой и имеет функции, назначенные каждому биту (проверьте кнопки количества).

Итак, моя следующая опция заключалась в том, чтобы сделать конфигурацию configusatorRows без шаблона и вместо этого использовать ng-transclude. Проблема в том, что наличие более одного configuratorRows в представлении, казалось, путалось с объемом для каждого из них. Так что в одном я мог бы иметь 4 строки, но в другом я мог бы иметь 2.

Кто-нибудь знает, как я могу обойти эту проблему элегантно?

ответ

1

Я не уверен, если я понимаю вашу цель правильно, но если вы хотите изменить шаблон директиву, в директиве вы можете сделать:

templateUrl: function(element,attrs){ 
    return attrs.type==='all' ? 'configuratorRows.all.tpl.html' : 'configuratorRows.single.tpl.html'; 
} 

Использование:

<div type="single" configurator-rows="controller.leisurewear" colours="controller.colours" ng-if="controller.leisurewear.length"></div> 
<div type="all" configurator-rows="controller.leisurewear" colours="controller.colours" ng-if="controller.leisurewear.length"></div> 
+0

Похоже, это был добавлен в угловых 1.3, и если вы не имеете требование к поддержки IE8, это лучший ответ. ** EDIT ** Nevermind, просто не в документации 1.2. –

+0

Да, я долго не знал об этой полезной функции ...: P – bl0u0l

0

One что вы могли бы сделать, хотя может быть немного сложнее настроить, чем вам может понравиться, - создать два разных файла шаблона configuratorBase.html и configuratorAlt.html и прикрепить их к двум различным директивам, разделяющим область действия (то есть неизолированную область) ,

.directive('configuratorBase', [function() { 
    var configuratorBase = { 
     restrict: 'AE', 
     templateUrl: '/path/to/configuratorBase.html' 
    }; 
    return configuratorBase; 
}); 

Тогда ваша директива конфигуратора может выглядеть примерно так:

.directive('configurator', ['$compile', function($compile) { 
    var configurator = { 
     restrict: 'AE', 
     link: configuratorLink(scope, element, attributes, controllers) { 
      /** if evaluating you need the base */ 
      var template = angular.element('<configuratorBase/>'); 
      $compile(element.append(template))(scope); 
     } 
    }; 
    return configurator; 
}); 
0

Если вы ищете «просто разные представления» те же структуры шаблона, вы, вероятно, нужен другой CSS подход (например, , в дерзости, посмотрите на bem approach)

Если вам нужна другая структура шаблона, вместо этого, вы должны выбрать шаблон на-среды выполнения (на основе, например, на templateUrl).

angular 
 
    .module('test', []) 
 
    .directive('tpl', function() { 
 
    return { 
 
     scope: { 
 
     type: '@' 
 
     }, 
 
     restrict: 'E', 
 
     //templateUrl: function(elem, attr){ 
 
     template: function(elem, attr){ 
 
     console.log('suca'); 
 
     var tpl = ''; 
 
     switch((attr.type || '').toLowerCase()) { 
 
      
 
      case 'heading': 
 
       tpl += '<h1>Heading</h1>'; 
 
       break; 
 
      
 
      default: 
 
       tpl += '<div">Normal Div Element </div>'; 
 
     } 
 
     
 
     return tpl; 
 
     } 
 
    }; 
 
    })
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<article data-ng-app="test"> 
 
    <tpl data-type="heading"></tpl> 
 
    <tpl></tpl> 
 
</article>

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