简体   繁体   English

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

[英]AngularJS: How to access directive controller's $scope properties in HTML

I have written an AngularJS directive for displaying tables. 我写了一个用于显示表的AngularJS指令。 I used these tables on few pages and it wokred awesome, and now I have a page where I need two instances of such table. 我在几页上使用了这些表,它的功能很棒,现在我有一个页面需要两个这样的表实例。 I am new to AngularJS and maybe it wasn't the best choise in the first place but so far I used the controllers scope for these tables and their directives. 我是AngularJS的新手,也许一开始并不是最佳选择,但到目前为止,我已将控制器范围用于这些表及其指令。 And when it comes to having two tables, they act like the same table when I change page for one table, the other one gets its page changed either, because they share the same scope (controller's scope). 当涉及到两个表时,当我为一个表更改页面时,它们的行为就像同一个表,而另一个更改了它的页面,因为它们共享相同的作用域(控制器的作用域)。

I added scope property to the directive declaration to accept items (this should be common for both tables) from the controller and within the directive's controller I declared filteredItems (this should not be common, each table should have its own filtered items list) property of the directive's scope. 我在指令声明中添加了scope属性,以接受来自控制器的items (这两个表应该是相同的),并且在指令的控制器内我声明了filteredItems (这应该是不常见的,每个表应该具有自己的过滤后的项目列表)指令的范围。

Now my controller goes like: 现在我的控制器如下所示:

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

    ...
}

My directive declaration is: 我的指令声明是:

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);
            }

            ...
        }
    };
}

And my HTML is: 我的HTML是:

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

    ...

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

        </tr>
    </tbody>

    ...

</div>

Directive's controller executes fine like it did before, but my problem is that for some reason in my html I can't access any properties for directive's isolated scope and I can't access these filteredItems . 指令的控制器像以前一样执行得很好,但是我的问题是,由于某种原因,在我的html中,我无法访问指令隔离范围的任何属性,也无法访问这些filteredItems If I replace data-ng-repeat="item in filteredItems" with data-ng-repeat="item in items" it displays the content because the view controller's scope has that property item but it won't iterate through filteredItems which is property of directive's scope. 如果我将data-ng-repeat="item in filteredItems"替换为data-ng-repeat="item in items"它会显示内容,因为视图控制器的作用域具有该属性item但不会遍历该属性的filteredItems指令范围。 And none other directive's scope properties can be accessed from there, I checked the scope id within the directive html content and it matches the id of the view's controller scope. 而且没有其他指令的作用域属性可以从那里访问,我检查了指令html内容中的作用域ID,它与视图的控制器作用域的ID相匹配。 Why within the directive's html I am dealing with view controller's scope and not with the directive's isolated scope? 为什么在指令的html中我要处理视图控制器的作用域而不是指令的隔离范围?

I don't think you can access your directive's isolated scope from outside the directive like that. 我认为您无法像这样从指令外部访问指令的隔离范围。 Can you make your directive wrap the table HTML like this: 您能否使指令像这样包装表格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 shows two tables using the same items filtered differently. 本示例显示了两个使用相同项目进行过滤的表。

I have slightly tweaked your example, here's the result: 我稍微调整了您的示例,结果如下:

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

Basically, it consists of the following: 基本上,它包括以下内容:

  • a mytable directive, it takes items array and produces a table with two rows - original numbers and odd (filtered) numbers 一个mytable指令,它接受items数组并生成一个包含两行的表-原始数字和奇数(已过滤)
  • a dataProducer service, it produces an array of 10 elements - each one calculates as index times provided multiplier. 一个dataProducer服务,它产生一个包含10个元素的数组-每个元素都将提供的乘数作为索引时间进行计算。
  • controller with couple of arrays, couple of multipliers and corresponding watchers. 带有几个数组,几个乘法器和相应观察器的控制器。

It works like so: you click on any button, that changes corresponding multiplier, controller's watcher updates corresponding data row, directive's watcher kicks in (because the data row changes) and invokes $scope.search() and that modifies local scope's filteredData property. 它的工作方式如下:单击任何按钮,更改相应的乘数,控制器的观察程序更新相应的数据行,指令的监视程序启动(因为数据行更改),并调用$scope.search()并修改本地范围的filteredData属性。 Two instances of this directive present on the page, and no scope clashing happens. 页面上存在此指令的两个实例,并且没有发生作用域冲突。

And if I'm not mistaken, you're trying to access properties belonged to a directive's scope from outside's HTML. 而且,如果我没记错的话,您尝试从外部HTML访问属于指令范围的属性。 That is simply won't work - just no way. 那根本行不通-只是没有办法。 If there's something calculated inside your directive and outside world needs to get access to it - move this logic to the controller. 如果您的指令内部计算出某些内容,并且外界需要访问该指令,请将此逻辑移至控制器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM