AngularJS:如何在HTML中访问指令控制器的$ scope属性

时间:2014-05-29 17:10:48

标签: javascript angularjs

我编写了一个用于显示表格的AngularJS指令。我在几页上使用了这些表,它很棒,现在我有一个页面,我需要这样的表的两个实例。我是AngularJS的新手,也许它不是最好的选择,但到目前为止我使用控制器范围来表示这些表及其指令。当涉及到两个表时,当我为一个表更改页面时,它们就像同一个表一样,另一个表也改变了页面,因为它们共享相同的范围(控制器的范围)。

我将范围属性添加到指令声明以接受来自控制器的items(这应该是两个表都是通用的),并且在我指定filteredItems的指令控制器中(这不应该很常见,每个表都应该有自己的过滤项列表)指令范围的属性。

现在我的控制器就像:

function ($scope, sgtService, ...) {
    sgtService.getList(function (data) {
        $scope.items = data;
    });

    ...
}

我的指示声明是:

abTable: function () {
    return {
        restrict: "A",
        scope: {
            items: '='
        },
        controller: function ($scope, $filter) {
            $scope.filteredItems = [];

            $scope.$watch('items', function () {
                $scope.search();
            });

            $scope.search = function () {
                $scope.filteredItems = $filter("filter")($scope.items, $scope.searchKeywords);
            }

            ...
        }
    };
}

我的HTML是:

<div data-ab-table="" data-items="items">

    ...

    <tbody>
        <tr data-ng-repeat="item in filteredItems">

        </tr>
    </tbody>

    ...

</div>

指令的控制器像以前一样执行得很好,但我的问题是,由于某种原因,在我的html中,我无法访问指令的独立范围的任何属性,而且我可以[&#39;访问这些filteredItems。如果我将data-ng-repeat="item in filteredItems"替换为data-ng-repeat="item in items",则会显示内容,因为视图控制器的范围具有该属性item,但它不会迭代filteredItems是指令范围的财产。并且可以从那里访问其他指令的范围属性,我检查了指令html内容中的范围ID,并且它匹配视图的控制器范围的id。为什么在指令的html中我处理视图控制器的范围而不是指令的独立范围?

2 个答案:

答案 0 :(得分:1)

我不认为你可以从指令外部访问你指令的独立范围。你可以让你的指令包装表格HTML:

.directive('abTable', function($filter){
  return {
    restrict: "A",
    replace: true,
    scope: {
      items: '=items',
      searchKeywords: '=searchKeywords' 
    },
    template: '<table><tr data-ng-repeat="item in filteredItems"><td>{{item.id}}</td><td>{{item.value}}</td></tr></table>',
    controller: function ($scope, $filter) {
        $scope.filteredItems = [];

        $scope.$watch('items', function () {
          $scope.search();
        });

        $scope.search = function () {
          $scope.filteredItems = $filter("filter")($scope.items, $scope.searchKeywords);
        }
    }
  };

This example显示两个表使用相同的项目进行了不同的过滤。

答案 1 :(得分:1)

我稍微调整了你的例子,结果如下:

http://jsfiddle.net/nmakarov/E5dm3/4/

基本上,它包含以下内容:

  • 一个mytable指令,需要items数组并生成一个包含两行的表 - 原始数字和奇数(已过滤)数字
  • 一个dataProducer服务,它生成一个包含10个元素的数组 - 每个元素都计算为提供乘数的索引时间。
  • 带有几个阵列的控制器,一对乘法器和相应的观察者。

它的工作原理如下:你点击任何按钮,改变相应的乘数,控制器的观察者更新相应的数据行,指令的观察者开始(因为数据行改变)并调用{{1并修改了本地范围的$scope.search()属性。该指令的两个实例出现在页面上,不会发生范围冲突。

如果我没有弄错的话,你可以尝试从外部的HTML访问属于指令范围的属性。这简直无法胜任 - 只是没办法。如果在您的指令中计算了某些内容并且外部世界需要访问它 - 将此逻辑移动到控制器。