简体   繁体   中英

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

I have written an AngularJS directive for displaying tables. 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. 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.

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:

<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 . 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. 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. Why within the directive's html I am dealing with view controller's scope and not with the directive's isolated scope?

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:

.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/

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
  • a dataProducer service, it produces an array of 10 elements - each one calculates as index times provided multiplier.
  • 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. 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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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