嵌套元素指令无法访问父指令范围

时间:2013-05-27 15:29:16

标签: angularjs element angularjs-directive

我一直在努力解决这个问题很长一段时间,我无法弄清楚如何解决这个问题。

我正在尝试创建一个包含用于描述网格的列指令的网格指令,但这些列不是元素,而只是将列添加到在网格指令范围内声明的数组中。

我认为解释此问题的最佳方法是查看代码:

var myApp = angular.module('myApp', [])

    .controller('myCtrl', function ($scope, $http) {
    })
    .directive('mygrid', function () {
        return {
            restrict: "E",
            scope: true,
            compile: function ($scope) {
                debugger;
                $scope.Data = {};
                $scope.Data.currentPage = 1;
                $scope.Data.rowsPerPage = 10;
                $scope.Data.startPage = 1;
                $scope.Data.endPage = 5;
                $scope.Data.totalRecords = 0;
                $scope.Data.tableData = {};
                $scope.Data.columns = [];
            },
            replace: true,
            templateUrl: 'mygrid.html',
            transclude: true
        };
    })
    .directive('column', function () {
        return {
            restrict: "E",
            scope: true,
            controller: function ($scope) {
                debugger;
                $scope.Data.columns.push({
                    name: attrs.name
                });

            }
        };
    });

这是HTML标记:

<body ng-app="myApp">
<div ng-controller="myCtrl">
    <input type="text" ng-model="filterGrid" />
    <mygrid>
        <column name="id">ID</column>
        <column name="name">Name</column>
        <column name="type">Type</column>
        <column name="created">Created</column>
        <column name="updated">Updated</column>
    </mygrid>
</div>

此外,您可以在jsfiddle:http://jsfiddle.net/BarrCode/aNU5h/

中测试实际代码

我尝试使用编译器,控制器和链接但由于某种原因,父网格的列未定义。

我该如何解决?

修改 当我从mygrid指令中删除replace,templateUrl,transclude时,我可以从column指令中获取范围。

由于

3 个答案:

答案 0 :(得分:1)

在AngularJS的更高版本中,我发现$ scope。$$ childHead做了我想要的。

它仍然是新的,但它也适用于具有隔离范围的指令。

所以在Columns指令中你可以这样做:

$scope.$$childHead.Data.columns.push({
                    name: attrs.name
                });

确保在编译网格后执行此命令。你可以这样做但是在编译,链接和控制器之间切换,因为它们中的每一个都有不同的加载优先级。

答案 1 :(得分:0)

我看到你正在尝试做什么,但使用column指令可能不是解决问题的最佳方法。

您正尝试使用可自定义的列定义grid指令。每列都有2条相关信息:用于访问行数据中值的键和要显示的标题。

暂时忽略所有与分页相关的内容,这是解决问题的另一种方法。

首先,让我们使用属性来定义列信息,因此我们的HTML看起来像:

<body ng-app='app' ng-controller='Main'>
    <grid col-keys='id,name,type'
          col-titles='ID,Name,Type'
          rows='rows'>
    </grid>
</body>

对于JS,我们显然需要app模块:

var app = angular.module('app', []);

这是grid指令。它使用隔离范围,但使用=双向绑定从其父范围获取行数据。注意链接函数如何从attrs对象中提取列信息。

模板变得非常简单:遍历列标题以定义标题,然后循环遍历rows,并在每一行中循环遍历列键。

app.directive('grid', function() {
    return {
        restrict: 'E',
        scope: {
            rows: '='            
        },
        link: function(scope, element, attrs) {
            scope.colKeys = attrs.colKeys.split(',');
            scope.colTitles = attrs.colTitles.split(',');
        },
        replace: true,
        template:
            '<table>' +
            '  <thead>' +
            '    <tr>' +
            '      <th ng-repeat="title in colTitles">{{title}}</th>' +
            '    </tr>' +
            '  </thead>' +
            '  <tbody>' +
            '    <tr ng-repeat="row in rows">' +
            '      <td ng-repeat="key in colKeys">{{row[key]}}</td>' +
            '    </tr>' +
            '  </tbody>' +
            '</table>'
    };
});

并开始使用一些示例数据。

app.controller('Main', function($scope) {
    $scope.rows = [
        {id: 1, name: 'First', type: 'adjective'},
        {id: 2, name: 'Secondly', type: 'adverb'},
        {id: 3, name: 'Three', type: 'noun'}
    ];
});

Here it is in fiddle form.

答案 2 :(得分:0)

正如Imri评论:

在AngularJS的更高版本中,您可以使用$scope.$$childHead

获取父指令

我还没有测试过。