2015-10-23 149 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>