从控制器访问指令元素

Access directive element from a controller

本文关键字:元素 指令 访问 控制器      更新时间:2023-09-26

在我的页面上,我有一个带有自定义指令的表,当用户单击详细信息按钮时显示行项的详细视图:

 <table ng-controller="MyController">
      <tr ng-repeat="item in controller.items">
        <td>{{item.name}}</td>
        <td> <a href="#" ng-click="controller.loadDetails(item.id)">details</a>
        </td>
      </tr>
      <tr ng-details details-colspan="2" ng-model="controller.details"></tr>
 </table>

指令:

.directive('ngDetails', function() {
    return {
        restrict: 'A',
        require: "^ngModel",
        replace: true,
        template: '<tr class="detailsTemplate {{ngModel.cssClass}}"> '
                      <td colspan="{{detailsColspan}}" ng-bind-html="ngModel.data"></td> '
                    </tr>',
        scope: {
          detailsColspan: '@',
          ngModel: '='
        }
    }
});
这是一个演示

目前项目详细信息部分显示良好,但它总是在表的底部。我想将我的指令行元素移动到相应的项目行下,但我不确定如何访问我的控制器内部的指令元素。

与其让details行只出现一次并四处移动,不如让ng-repeat在每行中都包含它。您可以在第一个<tr>上使用ng-repeat-start,在最后一个<tr>上使用ng-repeat-end。这种特殊的语法允许重复任意的元素集,而不包含在相同的重复元素中。然后,您可以在指令元素上包含ng-hide, ng-showng-if,仅在单击适当的行时显示。

关于ng-repeat-start/end语法的更多信息可以在这里找到。

你不应该在控制器中访问你的元素。如果你必须这样做,那么要么是你的应用设计有问题,要么是你对Angular本身的理解有问题。

一般来说,你应该开始把你的指令看作是HTML和业务逻辑(你的服务、库、模型等内部的实际JS代码)之间的粘合剂,并严格保持这种方式。


在这种特殊情况下,您可以将整个ng-repeat视为一个指令的一部分,并在每个项目行之间合并细节行。

更好的是,如果显示详细信息行需要用户进行一些操作,比如单击项目行,您可以动态地在单击的项目行下面添加/删除详细信息行。这将是更优的一点,因为细节数据将被"延迟"编译。