创建指令,用于将每个列表元素包装在引导程序面板中,并使用控件进行删除,重新排序,...

时间:2014-09-06 19:22:23

标签: javascript angularjs twitter-bootstrap angularjs-ng-repeat

我有一个angularjs应用程序,它为同一结构的复杂对象列表生成表单。我写了指令来创建编辑它们所需的html。

所以它基本上只是一个

<div ng-repeat="element in elements">
    <div element-directive="element"></div>
</div>

但是,我现在想添加重新排序和删除列表“elements”中的每个元素的可能性(并可选择添加新的元素)

因为我不想为每种类型反复实现控制和逻辑,所以我写了一个指令“repeatPanels”,它应该与ngRepeat一起使用。

<div ng-repeat="element in elements" repeatPanels="elements">
    <div element-directive ng-model="element">
</div>

将html转换为

<div ng-repeat="element in elements" repeat-panels="elements"><div class="panel panel-default">
  <div class="panel-heading">
    <div class="panel-title">
      <div class="btn-group pull-left"><button class="btn btn-sm btn-default"><span class="glyphicon glyphicon-move"></span></button></div>
      <div class="btn-group pull-right"><button ng-click="removeElement($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-remove"></span></button></div></div><div class="clearfix"></div>
    </div>
    <div class="panel-body">
      <div element-directive ng-model="element">
    </div>
  </div>
</div>
<div ng-repeat="element in elements" repeat-panels="elements"><div class="panel panel-default">
  <div class="panel-heading">
    <div class="panel-title">
      <div class="btn-group pull-left"><button class="btn btn-sm btn-default"><span class="glyphicon glyphicon-move"></span></button></div>
      <div class="btn-group pull-right"><button ng-click="removeElement($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-remove"></span></button></div></div><div class="clearfix"></div>
    </div>
    <div class="panel-body">
      <div element-directive ng-model="element">
    </div>
  </div>
</div>

(参见this Plunker)获取完整示例)

所以它已经在引导程序面板中的ngRepeat中包含了html,其中包含用于删除元素的按钮,以及用于ui-sortable的draggables。

但是,我坚持实现删除按钮的功能。 ng-repeat中的所有html都使用“原始”范围,因此在repeatPanels指令范围内定义函数将不起作用:-(

对于ui-sortable,我也不确定是否只是将ui-sortable和ng-model属性添加到原始ng-repeat节点工作的父元素中,或者还有更多要做的事情......

有人能指出我正确的方向吗?

谢谢!

弗洛里安

1 个答案:

答案 0 :(得分:0)

首先你需要$编译你的自定义模板:

$compile(element.contents())(scope);

现在,您的内部模板已绑定到您的隔离范围,因此我将ng-repeat移动到自定义模板中:

link: function (scope, element, attrs) {
        var panelHeadingHtml = '<div  class="panel-heading">' +
            '<div class="panel-title">' +
            '<div class="btn-group pull-left">' +
            '<button class="btn btn-sm btn-default"><span class="glyphicon glyphicon-move"></span></button>' +
            '</div>' +
            '<div class="btn-group pull-right">' +
            '<button ng-click="removeElement($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-remove"></span></button>' +
            '</div>' +
            '</div>' +
            '<div class="clearfix"></div>' +
            '</div>';
        element.wrapInner('<div ng-repeat="element in repeatPanelsElements"  class="panel panel-default"><div class="panel-body"></div></div>');
        element.find(" > .panel").prepend(panelHeadingHtml);
        $compile(element.contents())(scope);
    }

这会将html更改为:

<div class="element" repeat-panels="elements">

这样做的一个原因是你在实施ng-repeat方面失去了一些灵活性。

另一个成本是外部范围不再直接与隔离范围通信,因此您可能需要创建以下事件:

scope {
    onDelete: '&'
}
例如,

调用持久层。

Plunkr此处。