角度表指令

时间:2014-10-02 10:46:09

标签: angularjs angularjs-directive angularjs-ng-repeat

我想制作表格指令,但我不知道该怎么做。这是我的源代码。

指令:

InterfaceModule.directive('gList', function() {
    return {
        restrict: 'AEC',
        transclude: true,
        templateUrl: 'interface/gList.html'
    };
});

gList.html:

<table class="table table-condensed">
<tr>
    <td style="width: 20px">
        <span class="icon-f-gear-small"></span>
    </td>
    <td ng-transclude>

    </td>
</tr>
</table>

控制器:

App.controller('ResultController', ['$scope', function($scope) {
    $scope.testItems = ['element 1', 'element 2', 'element 3']
}])

html代码:

<div ng-controller="ResultController">
    <g-list>
        <a href="#" ng-click="someFunction()">{{item}}</a>
    </g-list>
</div>

我需要在<tr>标签中使用ng-repeat,虽然我不想在指令模板中使用它,但我希望它在我的主html文件中使用。如果我在g-list标签(<g-list ng-repeat="item in testItems">)中使用它我得到单独的表到数组中的每个元素,我需要一个表和行数等于数组大小(在这种情况下一个表有3行)。所以问题是如何改变我的指令,就像我解释的那样。提前谢谢!

更新

谢谢你的回答。 现在它更清楚了,但我还有几个问题。主要的想法是,我希望在最后这样的事情:

<g-list icon="gear-small">
     <g-entry function="someFunction()">Sąrašo elementas 1</g-entry>
     <g-entry link="/some/url" count="20">Sąrašo elementas 2</g-entry>
     <g-entry link="/some/url" disabled="Netinkama objekto būsena">Sąrašo elementas 3</g-entry>
</g-list>

我将需要调用函数的条目,并且将有条目我将不得不去clik事件的某个URL。

2 个答案:

答案 0 :(得分:1)

您能解释一下您想要实现的目标以及您不希望在指令中使用ng-repeat的原因吗?是因为你想在其他地方重用模板吗? 乍一看,我没有看到任何方法将指令保持在表级而不包括ng-repeat,除非你准备完全消除它并转换它的所有内容。如果您可以使用“tr”指令,这将是保持ng-repeat超出指令的最简单方法:我将指令限制为<tr>并将table直接放在您的指令中HTML代码。

<div ng-controller="ResultController">
    <table class="table table-condensed">
        <g-list ng-repeat="item in items" src="item" fcn="someFunction()">

        </g-list>
    </table>
</div>

现在您的模板看起来像:

<tr>
    <td style="width: 20px">
        <span class="icon-f-gear-small"></span>
    </td>
    <td >
        <a href="#" ng-click="fcn()">{{src}}</a>
    </td>
</tr>

你的指令需要

scope {
   src:'=',
   fcn:'&'
}

根据您想要实现的目标以及您对ng-repeat的关注点,还有其他一些事情需要探讨:您可以在模板中使用ng-include,您可以放弃转换并通过功能到您的指令...更多信息将不胜感激。

已编辑以删除翻译)

编辑2:好的,这是一个有两个不同条目的准系统解决方案。有些事情可能会有所改进,代码可能会根据您的具体需求略有变化 假设:您的项目如下:

item : {
    type:yyy, // can take 'url' and 'function' 
    value:xxx
}

interface / entry1.html,带有函数

<tr>
    <td style="width: 20px">
        <span class="icon-f-gear-small"></span>
    </td>
    <td >
        <a href="#" ng-click="fcn()">{{item.value}}</a>
    </td>
</tr>

interface / entry2.html,带有网址

<tr>
    <td style="width: 20px">
        <span class="icon-f-gear-small"></span>
    </td>
    <td >
        <a href="{{item.url}}">{{item.value}}</a>
    </td>
</tr>

interface / gList.html,指令模板(ng-repeat返回)

<table class="table table-condensed">
    <div ng-repeat="item in items" ng-switch="item.type">
        <ng-include src="'interface/entry1.html'" ng-switch-when="function"/>
        <ng-include src="'interface/entry2.html'" ng-switch-default/>
    </div>
</table>

directive.js

InterfaceModule.directive('gList', function() {
    return {
        scope {
            items:'=',
            fcn:'&'
        }
        restrict: 'AEC',

        templateUrl: 'interface/gList.html'
    };
});

html代码

<div ng-controller="ResultController">
    <g-list items="myItems" fcn="someFunction()">
</div>

请注意,指令范围现在与主范围隔离,因此无法访问任何未明确提供的范围变量(此处为items和fcn)。如果你想避免过多的交互和混乱,这通常是一个很好的做法(尽管仍然存在一些交互:“=”表示双向绑定,因此更改指令中的项目将在主范围内重新选择)。 昂再次,有多种方法可以做到这一点。例如,您可以完全放弃gList并为gEntry创建一个小指令,然后循环它。这样,您可以直接将“类型”提供给指令,而不是将其添加到项目中。

答案 1 :(得分:0)

here进行了一些调整,这里是一个带有重复内部模板和范围传递引用的指令的代码:

app.directive('myTable', function($compile){
  return {
    restrict: 'E',
      scope: {
          items: '='
      },
      compile: function (tElement) {
          // Extract the children from this instance of the directive
          var children = tElement.children();

          var tableTemplate =
              '<table>' +
              '<tr ng-repeat="item in items">' +
                  '<td>first column</td>' +
                  '<td insert></td>' +
              '</tr>' +
              '</table>';

          var table = angular.element(tableTemplate);

          // Find the 'insert' attribute and append children
          angular.element(table[0].querySelector('[insert]'))
              .append(children)
              .removeAttr('insert');

          // Append this new template to the directive element
          tElement.html('');
          tElement.append(table);

          // Create a compile function that we can call from the linker
          var compile = $compile(table);

          return function(scope) {
              // In the linker, compile against the scope
              compile(scope);
          };
    }
  };
});

Here's an example in JSFiddle

如果您想从其他地方导入模板,可以使用$templateCache