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

是的,正如您在第二个选项中描述的那样,我已经这样做了。

我创建了一个指令,该指令加载特定模板,然后根据数据的类型属性在其中包含其他指令。

    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

您的第二个解决方案听起来更适合角度。因此,如果它只是一个动态添加的指令

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)if (attrs.dynamically.indexOf(' ')以便您可以在一个实例中实现多个指令,在此示例中由空格字符 (' ') 分隔。

2)我通过询问将'="true"'添加到我使用的属性中if (attrs.x) {...},如果属性x没有值,即使在DOM上声明和定位它也不存在。

于 2013-09-06T19:35:23.283 回答