Child指令无法访问父控制器

时间:2016-02-10 17:50:27

标签: angularjs directive angularjs-ng-transclude

我有2个指令创建一个网格表。 对于每一行,我们可能会有一些操作,我的问题是我可以以某种方式访问​​这些操作而无需在我的模板中调用$ parent。$ parent.action吗?

            .directive("grid", function ($compile, $parse) {
            return {
                restrict: 'AE',
                scope:  {
                    templateUrl         : '@?',
                    columns             : '=',
                    filterBy            : '=?',
                    excludeSortColumns  : '=?'
                },
                controller: GridController,
                controllerAs: 'grid',
                bindToController: true,
                replace: true,
                transclude: true,
                templateUrl: function($element, $attrs) {
                    if(!angular.isDefined($attrs.filterBy)) {
                        return '/assets/js/src/templates/partials/grid/grid-sortable.tpl.html';
                    }
                    return $attrs.templateUrl || '/assets/js/src/templates/partials/grid/grid.tpl.html';
                },
                link: function($scope, $element, $attrs, ctrl, transclude) {
                    //filter collection when user has typed some letter
                    $element.on('keyup', function() {
                        $scope.$apply(function() {
                            $scope.$parent.filterValue = $('.filterBy').val();
                        });
                    });
                    //var e = $compile(transclude())($scope.$parent);
                    //angular.element('.table').append(e);
                    $element.append(transclude($scope.$parent));
                }
            };

            function GridController($scope, $element, $attrs) {
                var vm = this;

                vm.columns = $parse($attrs.columns)($scope.$parent);
                vm.excludeSortColumns = angular.isDefined($attrs.excludeSortColumns) ? $parse($attrs.excludeSortColumns)($scope.$parent) : false;
                vm.filterCol = angular.isDefined($attrs.filterBy) ? $parse($attrs.filterBy)($scope.$parent) : false;

                vm.sortBy = function(column) {
                    if(!vm.isExludedSortBy(column)) {
                        vm.predicate = column;
                        vm.reverse = (vm.predicate === column) ? !vm.reverse : false;
                        var sortType = (vm.reverse) ? '-' : '+';
                        $scope.$parent.orderByColumn = sortType + column;
                    }
                };

                vm.isExludedSortBy = function(column) {
                    if(!vm.excludeSortColumns) {
                        return true;
                    }
                    if(vm.excludeSortColumns.indexOf(column) >= 0) {
                        return true;
                    }
                    return false;
                };
            };
        })

        .directive("gridBody", function ($parse) {
            return {
                restrict: 'AE',
                scope:  {
                    templateUrl         : '@?',
                    collection          : '='
                },
                require: '^grid',
                controller: function($scope, $element, $attrs) {
                    var vm = this;
                    vm.collection = $parse($attrs.collection)($scope.$parent);
                },
                controllerAs: 'body',
                bindToController: true,
                replace: true,
                transclude: false,
                templateUrl: function($element, $attrs) {
                    return $attrs.templateUrl || '/assets/js/src/templates/partials/grid/grid-body.tpl.html';
                }
            };
        })

这是一个模板:

<tbody>
    <tr ng-repeat="item in body.collection | gridFilterBy:$parent.filterBy:$parent.filterValue | orderBy:$parent.orderByColumn track by $index">
        <td class="col-sm-1">{{item.id}}</td>
        <td class="col-sm-2">{{item.name}}</td>
        <td class="col-sm-1">{{item.latest_result.count}}</td>
        <td class="col-sm-2">{{item.created_at}}</td>
        <td class="col-sm-2">{{item.updated_at}}</td>
        <td class="col-sm-4">
            <button class="btn btn-primary" ng-disabled="item.has_cluster" role="button" ng-click="$parent.$parent.addCluster(item.id)">
                Crea cluster
            </button>
            <button class="btn btn-primary" role="button" ng-click="$parent.getExports(item.id, item.name)">
                Export
            </button>
            <button class="btn btn-primary" role="button" ng-click="$parent.$parent.loadQuery(item.id)">
                Visualizza
            </button>
            <button class="btn btn-primary" role="button" ng-click="$parent.$parent.removeQuery(item.id)">
                Rimuovi
            </button>
        </td>
    </tr>
</tbody>

            <grid columns="columns" filter-by="filterBy" exclude-sort-columns="excludeColumns">
            <grid-body collection="result.items" template-url="/assets/js/src/templates/partials/grid/grid-body.tpl.html"></grid-body>
        </grid>

我无法获得网格控制器

感谢所有回复。

1 个答案:

答案 0 :(得分:0)

通常这是通过指令控制器完成的。以下是设置父和子指令控制器以使彼此了解的示例:

app.directive('parentDir', function() {
  return {
    restrict: 'A',
    controller: function($scope, $element, $attrs) {
      this.parentInit = function(ctrl) {
        console.log(ctrl);
      };

      this.parentClick = function(param) {

      };
    },
    link: function(scope, element, attrs) {

    }
  }
});

app.directive('childDir', function() {
  return {
    restrict: 'A',
    require: ['childDir', '^parentDir'],
    controller: function($scope, $element, $attrs) {
      var parentCtrl;
      this.childInit = function(parentCtrl) {
        console.log(parentCtrl);
        parentCtrl = ctrl;
      };

      $scope.childClick = function(param) {
        parentCtrl.parentClick(param);
      };
    },
    link: function(scope, element, attrs, ctrls) {
      ctrls[0].childInit(ctrls[1]);
      ctrls[1].parentInit(ctrls[0]);
    }
  }
});

这是一个带有演示的plunk