2014-01-15 110 views
3

我是Angular的初學者,但我正在探索一些稍微更先進的角落以確保它具有我需要的功能。角度動態多態指令

具體我需要:

  • 呈現與每個作爲一個獨立的角指令
  • 微件類型是從數據確定,而不是由標記
  • 小部件實現的不同類型的窗口小部件的一個序列各自定義在單獨的文件中
  • 將指令的範圍設置爲該小部件實例的數據

我想我已經解決了以下說明,並在http://jsfiddle.net/cUTt4/5/

問題實施的要求:

  1. 這是正確的,最佳實踐,和相當快?
  2. 我應該添加哪些改進?
  3. 如果widget指令沒有顯式引用{item:'='}來獲得它們的隔離範圍,但它們的子範圍應該由renderform指令構建,那會更好。我怎麼做?

我的解決辦法: HTML (注角模板腳本這裏因的jsfiddle的限制)

<div ng-app="myApp"> 

    <script type="text/ng-template" id="widget-type-a"> 
     <div> 
      <label>{{ item.label}} </label> 
      <input type="text" ng-model="item.val" > 
     </div> 
    </script> 

    <script type="text/ng-template" id="widget-type-b"> 
     <div> 
      <label>{{ item.label}}</label> 
      <input type="text" ng-model="item.val" > 
     </div> 
    </script> 

    <div ng-controller="FormCtrl"> 
     <renderform></renderform> 
    </div> 
</div> 

main.js:

var app = angular.module('myApp', []); 

function FormCtrl($scope) { 
    items = [ 
     { 
      type: 'widget-type-a', 
      label : 'Widget A instance 1', 
      val: 1 
     }, 
     { 
      type: 'widget-type-b', 
      label : 'Widget B instance 1',  
      val : 2 
     }, 
     { 
      type: 'widget-type-a', 
      label : 'Widget A instance 2', 
      val : 3 
     } 
    ]; 
    $scope.items = items 

} 

app.directive('renderform', function($compile) { 
    function linkFn(scope, element) { 
     var item, 
      itemIdx, 
      templStr = '', 
      newParent, 
      data, 
      newEl; 

     newParent = angular.element('<div></div>') 
     for(itemIdx in scope.items) { 
      item = items[itemIdx]; 
      templStr += '<div ' + item.type + ' item="items[' + itemIdx + ']"></div>'; 
     } 
     newEl = angular.element(templStr); 
     $compile(newEl)(scope); 
     element.replaceWith(newEl); 
    } 

    return { 
     restrict: 'E', 
     link:linkFn 

    }; 

}); 

app.directive('widgetTypeA', function() { 
    return { 
     restrict: 'A', 
     templateUrl: 'widget-type-a', 
     scope: { item: '=' } 
    }; 

}); 

app.directive('widgetTypeB', function() { 
    return { 
     restrict: 'A', 
     templateUrl: 'widget-type-b', 
     scope: { item: '='} 
    }; 

}); 
+0

你的jsfiddle似乎丟幾個錯誤。 –

+0

謝謝Michal,我沒有保存加載選項。上面的鏈接現在應該在FF/Chrome中運行。 – pwray

回答

3

對不起快答案,而不是測試:

<div data-ng-repeat="item in items"> 
    <div data-ng-switch data-on="item.type"> 
    <div data-ng-switch-when="widget-type-a" data-widget-type-a="item"></div> 
    <div data-ng-switch-when="widget-type-b" data-widget-type-b="item"></div> 
    </div> 
</div> 

如果這是您要找的內容,請改善此答案。

+0

請參閱https://docs.angularjs.org/api/ng/directive/ngSwitch – Eldloppa

1

我一直在考慮這個問題一段時間了,雖然ng-switch選項適用於簡單的情況,但它引入了相當多的維護開銷。

我想出了一個允許單點維護的解決方案。考慮以下幾點:

var app = angular.module('poly', []); 
 

 

 
app.controller('AppController', function ($scope) { 
 
    $scope.items = [ 
 
     {directive: 'odd-numbers'}, 
 
     {directive: 'even-numbers'}, 
 
     {directive: 'odd-numbers'} 
 
    ]; 
 
}); 
 

 

 
app.directive('component', function ($compile) { 
 
    return { 
 
     restrict: 'E', 
 
     controller: function() { 
 

 
     }, 
 
     controllerAs: 'component_ctrl', 
 
     link: function (scope, element, attrs) { 
 
      var child_directive = scope.$eval(attrs.directive); 
 
      var child_element = $compile('<' + child_directive + ' data="data"></' + child_directive + '>')(scope); 
 
      element.append(child_element); 
 
     } 
 
    } 
 
}); 
 

 

 
app.directive('oddNumbers', function ($interval) { 
 
    return { 
 
     restrict: 'E', 
 
     link: function (scope) { 
 
      scope.number = 0; 
 
      $interval(function() { 
 
       scope.number += 2; 
 
      }, 1000); 
 
     }, 
 
     template: '<h1>{{ number }}</h1>' 
 
    } 
 
}); 
 

 

 
app.directive('evenNumbers', function ($interval) { 
 
    return { 
 
     restrict: 'E', 
 
     link: function (scope) { 
 
      scope.number = 1; 
 
      $interval(function() { 
 
       scope.number += 2; 
 
      }, 1000); 
 
     }, 
 
     template: '<h1>{{ number }}</h1>' 
 
    }; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<section ng-app="poly" ng-controller="AppController"> 
 
    <div ng-repeat="item in items"> 
 
    <component directive="item.directive" data="item.data"></component> 
 
    </div> 
 
</section>

這允許在控制器在自組織的方式來指定的組件和不具有委派經由開關責任中繼器。

NB我並沒有實現數據是如何組件之間傳遞