2015-10-23 117 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覆盖,但后来我意识到我放置此伪指令的区域也是一个指令,并且具有分配给每个位的功能(检查数量按钮)。

所以我的下一个选择是制作配置器行指令没有模板,只是使用ng-transclude来代替。问题在于,在一个视图中有多个配置器行似乎混淆了每个人的范围。所以在一个我可能有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支持的要求,这是更好的答案。 **编辑**没关系,只是不在1.2文档中。 –

+0

是的,我很久没有知道这个有用的功能...:P – bl0u0l

0

一你可以做的事情,尽管设置起来比创建两个不同的模板文件configuratorBase.htmlconfiguratorAlt.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>