动态网格作为自定义指令

dynamic grid as custom directive

我对 Angular 比较陌生,并且卡在自定义指令上。 我正在尝试创建一个动态网格作为自定义指令。 我已经让那个部分像这个例子一样工作了:

working grid as custom directive

在某些情况下,我需要在网格的某些元素上设置属性。 这部分让我难住了。 我计划将属性作为数组包含在对象中,然后将其放入关联条目的 html 标记中。 这部分演示在这里:

broken grid as custom directive with dynamic attributes

如果您查看控制器中的 "entries" 数组,我现在将其更改为包含一个 "attributes" 数组,该数组将包含指定属性名称和 属性 的对象。然后应将这些属性应用于关联的列。

例如

(First entry of the array)
col1: {
  text: 'Obj1.col1',
  attributes: [{
    attr: 'ng-class',
    attrVal: 'propVal == "" ? "someClass" : "someOtherClass"'
  }, {
    attr: 'id',
    attrVal: '{{propName}}{{$index}}'
  }]
},
...Truncated for brevity

此数组条目应转换为:

<td ng-class="propVal == '' ? 'someClass' : 'someOtherClass'" id="col11">Obj1.col1</td>

我已经阅读了几篇关于编译、控制器、pre-link 和 post-link 函数的执行顺序的文章,并尝试了不同的顺序并尝试调用编译我自己,但这一切都失败了。 可能是因为我对它们如何联系在一起缺乏更深入的了解。 如果有人能帮助我或在我走错路时指出正确的方向,我将不胜感激。

好的,我终于想出了如何使用父自定义指令中的嵌入式自定义指令动态生成网格。

这里有一个 plunker 展示了我是如何做到的:

Plunker with working dynamic grid

我将 Html 模板 定义为:

<div ng-grid ng-collection="entries" ng-collection-headings="headings" ng-button-click="theAction(inp)">
    <div ng-checkbox-column></div>
</div>

然后 ng-grid 指令 为:

.directive("ngGrid", function () {
    return {
        restrict: "A",
        scope: {
            ngCollectionHeadings: "=",
            ngCollection: "=",
            ngButtonClick: "&"
        },
        template: function (element, attrs) {
            var children = element.html();
            children = children.trim().replace(/div/g, "td");
            var htmlText = "<input type='button' ng-click='buttonClicked()' value='From the grid directive' /><table class='table table-bordered'><thead><tr><th ng-repeat='heading in ngCollectionHeadings'>{{heading}}</th></tr></thead><tbody><tr id='item{{$index}}' ng-repeat='item in ngCollection'>" + children + "</tr></tbody></table>";
            return htmlText;
        },
        controller: function ($scope, $element) {
            $scope.buttonClicked = function (inp) {
                if (typeof inp != 'undefined')
                  inp = inp + ", through the grid directive.";
                else
                  inp = "From the grid directive.";

                $scope.ngButtonClick({ inp: inp });
            };
        }
    };
})

最后是 ng-checkbox-column 指令:

.directive("ngCheckboxColumn", function () {
    return {
        restrict: "A",
        template: function (element, attributes) {
            var htmlText = "<td><label><input type='checkbox' ng-model='item.checked' ng-click='tempButtonClicked()' /> From the checkbox directive.</label></td>";

            return htmlText;
        },
        controller: function ($scope, $element) {
          $scope.tempButtonClicked = function () {
              var val = "From the checkbox directive";
              $scope.buttonClicked(val);
          };
        }
    };
})

我的数据收集非常简单:

$scope.headings = {
    head1: 'Heading 1',
    head2: 'Heading 2',
    head3: 'Heading 3'
};

$scope.entries = [{
    col1: 'Obj1.col1',
    col2: 'Obj1.col2',
    col3: 'Obj1.col3',
    checked: false
}, {
    col1: 'Obj2.col1',
    col2: 'Obj2.col2',
    col3: 'Obj2.col3',
    checked: false
}, {
    col1: 'Obj3.col1',
    col2: 'Obj3.col2',
    col3: 'Obj3.col3',
    checked: false
}, {
    col1: 'Obj4.col1',
    col2: 'Obj4.col2',
    col3: 'Obj4.col3',
    checked: false
}];

这还没有完全完成,但是你应该了解了基本的想法。