在指令中调用模板后,$ scope变为null

时间:2015-06-21 14:45:18

标签: angularjs angularjs-directive directive

我有一个像这样的嵌套指令

app.directive('grid', ['$log', '$http', function ($log , $http) {
    return {
        restrict: 'E',
        scope: {},
        //template: '<span></span>', //i uncomment this line
        controller: function ($scope, $element, $attrs){
            var swColumns = [];
            this.setColumns = function (columns) {
                swColumns = columns;
                $log.log('grid controller');
                $log.log(columns);
                $scope.swColDefs = columns;
                $log.log($scope.swColDefs);
            };

            this.getColumns = function () {
                return swColumns;
            };
        },
        link: function (scope, element, attrs, gridController) {
            $log.log('grid link');
            $log.log(gridController.getColumns());
            $log.log(scope.swColDefs);
        }
    };
}]);
app.directive('gridColumns', ['$log', function ($log) {
    return {
        restrict: 'E',
        require: ['^grid', 'gridColumns'],
        controller: function () {
            var columns = [];
            this.addColumns = function (column) {
                columns.push(column);
            };
            this.getColumns = function () {
                return columns;
            };
        },
        link: function (scope, element, attrs, controllers) {
            var gridController = controllers[0];
            var gridColumnsController = controllers[1];
            gridController.setColumns(gridColumnsController.getColumns());
        }
    };
}]);

在我取消注册grid指令中的模板之前,每件事都可以 之后,网格链接函数中的swColDefs变为空数组 我的代码出了什么问题?

<grid>
  <grid-columns>
  </grid-columns>
  ...
</grid>

我正在使用它

2 个答案:

答案 0 :(得分:1)

虽然问题没有说明,但我假设你正在使用你的指令:

<grid>
  <grid-columns>
  </grid-columns>
  ...
</grid>

但是,由于您正在指定<grid>的模板,因此Angular会删除内容并设置模板。因此,gridColumns指令永远不会编译,link函数永远不会运行。

这是grid需要进行转换的地方。 Transclusion从DOM中获取内容,编译它(在编译阶段),然后允许您将它与您需要的任何范围相关联,并将其放在内容中。

从您的问题中不清楚哪个范围gridColumns指令需要链接,以及它是否有任何可视组件。

对于简单的转换案例,可以使用<ng-transclude>模板中的grid来完成此操作:

transclude: true,
template: "<span>whatever</span><div ng-transclude></div>" // template of grid

或者,为了更精确地控制范围和位置,您可以使用transclude函数(作为第五个参数传递给link函数):

transclude: true,
template: "<span>whatever</span>",
link: function(scope, element, attrs, gridController, transclude){
  transclude(function(transcludedContent){
     // place the content where needed, if at all
  });
}

答案 1 :(得分:0)

我已经在网格模板中解决了这个问题 首先,我添加一个带有ng-transclude的div到模板 secod transclude:在网格指令中为true

app.directive('grid', ['$log', '$http', function ($log , $http) {
    return {
        restrict: 'E',
        scope: {},
        transclude:true,//my change
        template: '<span>
                   <div ng-transclude>//my change
                   </div>
                   </span>',
        controller: function ($scope, $element, $attrs){
            var swColumns = [];
            this.setColumns = function (columns) {
                swColumns = columns;
                $log.log('grid controller');
                $log.log(columns);
                $scope.swColDefs = columns;
                $log.log($scope.swColDefs);
            };

            this.getColumns = function () {
                return swColumns;
            };
        },
        link: function (scope, element, attrs, gridController) {
            $log.log('grid link');
            $log.log(gridController.getColumns());
            $log.log(scope.swColDefs);
        }
    };
}]);