6

データの配列からダッシュボードを動的に構築しています。ゲージはD3です。

AngularJS ディレクティブで定義されたさまざまな D3 ゲージを選択しました。私のページには、メトリック配列を反復する ng-repeat があります。

私が持っている質問は、ng-repeat 配列内のデータの属性に基づいて適切なディレクティブを動的に選択する最良の方法は何ですか?

使用されるディレクティブが配列からの入力値に基づくファクトリ パターンを作成する方法はありますか? または、ディレクティブに他のディレクティブを動的に含めることにより、ディレクティブのみを使用して結果を達成する方法はありますか?

HTML

<div ng-controller="DashboardCtrl">
<div id="oppChart">
    <div>
        <gh-visualization ng-repeat="item in metrics" val="item[0]"></gh-visualization>
    </div>
</div>
</div>

メトリクス配列 (動的になります):

$scope.list = [
        { 'title': 'XYX','data-type':'', 'query':'SELECT ...' },
        { 'title': 'Revenue', 'data-type':'', 'query':'SELECT ...'  }
      ];

これに基づく D3 ディレクティブ - http://briantford.com/blog/angular-d3.html

4

3 に答える 3

6

それはng-switch

<div ng-repeat="item in metrics">
  <div ng-switch on="item.type">
    <div ng-switch-when="optionA">..include </div>
    <div ng-switch-when="optionA">..include </div>
  </div>
</div>
于 2013-09-06T19:38:36.163 に答える
1

はい、2番目のオプションで説明したようにこれを行いました。

データの type 属性に基づいて他のディレクティブを含む特定のテンプレートをロードするディレクティブを作成しました。

    directive("dynamicFormInput", ['$http', '$templateCache', function($http, $templateCache){
    return {
        restrict: 'E',
        //currently need model for map center otherwise can be removed, need to set default in map directive
        scope: {model: '=', section: '='},
        template: '<ng:include src="tpl"></ng:include>',
        link: function(scope, iElement, iAttrs) {
            var sectionToLoad = "";
            switch(scope.section.sectionTypeId)
            {
                case 1:
                    sectionToLoad ='partials/survey/textInput.html';
                  break;
                case 2:
                    sectionToLoad = 'partials/survey/selectOneOption.html';
                  break;
                case 3:
                    sectionToLoad = 'partials/survey/multiSelectOption.html';
                  break;
                case 4:
                    sectionToLoad = 'partials/survey/boolean.html';
                  break;
                case 5:
                    sectionToLoad = 'partials/survey/textInput.html';
                  break;
                case 6:
                    if(scope.section.sectionId == 13)
                        sectionToLoad = 'partials/survey/addressSelection.html';
                    else if(scope.section.sectionId == 24)
                        sectionToLoad = 'partials/survey/contactForm.html'
                break;
            }
            if(sectionToLoad!="")
            {
                $http.get(sectionToLoad, {cache:$templateCache});
                scope.tpl=sectionToLoad;
            }
        }
    }
}])

使用法は次のようになります。

<accordion
    close-others="true">
    <accordion-group
        ng-repeat="section in sections"
        ng-class="{'isGroundTruthed':section.userId==73}"
        heading="{{section.sectionName}} ({{displaySelection(section)}})">

        <dynamic-form-input
            section="section">
        </dynamic-form-input>

    </accordion-group>
</accordion>

各セクションが折りたたまれるように、たまたまそれを繰り返すアイテムとして使用したアコーディオンは無視できます。

編集 ディレクティブコードをいくつかクリーンアップしました。

于 2013-09-06T19:36:46.593 に答える
0

あなたの2番目のソリューションは、より角度的に適切に聞こえます。したがって、動的に追加される単一のディレクティブのみの場合

app.directive('dynamically',function(){ 
  return {
    restrict: 'A',
    compile: function(element,attrs){
      var directives = [];
      if (attrs.dynamically.indexOf(' ') > -1){
        directives = attrs.dynamically.split(' ')
      } else {
        directives.push(attrs.dynamically)
      };
      var html = '<ANY ';
      for (var i in directives){
        html += directives[i] + '="true" ';
      };
      html += '></ANY>';
      element.replaceWith(html)
    }
  }
})

それはそれを行う1つの方法です。

1)if (attrs.dynamically.indexOf(' ')は、この例ではスペース文字 (' ') で区切られた複数のディレクティブを 1 つのインスタンスに実装できるようにするためのものです。

2)if (attrs.x) {...}属性 x に値がない場合は、DOM に記述されて配置されていても存在しません。

于 2013-09-06T19:35:23.283 に答える