Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS:访问包含嵌套ng repeat的转置指令中的父作用域_Javascript_Angularjs_Angularjs Directive_Transclusion - Fatal编程技术网

Javascript AngularJS:访问包含嵌套ng repeat的转置指令中的父作用域

Javascript AngularJS:访问包含嵌套ng repeat的转置指令中的父作用域,javascript,angularjs,angularjs-directive,transclusion,Javascript,Angularjs,Angularjs Directive,Transclusion,我正在编写一个基本指令,该指令创建一个适合引导的div网格。您可以为它提供一个项目集合,并可以选择指定它可以包含的列数。它是转置的,因此您可以定义为每个项目显示的模板 我将集合拆分为行,然后使用嵌套的中继器,第一个中继器创建每一行,第二个中继器创建每一列(然后转移该项的内容)。它在这个简单的场景中运行良好 .directive('grid', [function() { return { restrict: 'AE', template:

我正在编写一个基本指令,该指令创建一个适合引导的div网格。您可以为它提供一个项目集合,并可以选择指定它可以包含的列数。它是转置的,因此您可以定义为每个项目显示的模板

我将集合拆分为行,然后使用嵌套的中继器,第一个中继器创建每一行,第二个中继器创建每一列(然后转移该项的内容)。它在这个简单的场景中运行良好

 .directive('grid', [function() {
    return {
            restrict: 'AE',
            template: '<div class="row" ng-repeat="row in rows"><div ng-repeat="item in row" ng-class="{\'col-md-{{columnSpan}}\': true, \'active\': isSelected(item) }"><div class="thumbnail" ng-transclude=""></div></div></div>',
            transclude: true,
            scope: {
                items: '=grid',
                columns: '@',
                columnSpan: '@'
            },
            controller: [
                '$scope', function($scope) {
                }
            ],
            link: function($scope, $el, $attrs) {
                $attrs.$observe('columns', function(val) {
                    $scope.columns = val || 4;
                });

                $attrs.$observe('columnSpan', function(val) {
                    $scope.columnSpan = val || 12 / $scope.columns;
                });

                $scope.$watchCollection('items', function(items) {
                    $scope.rows = $scope.rows || [];
                    $scope.rows.length = 0;

                    if (!items) return;

                    var numRows = Math.floor(items.length / $scope.columns);
                    numRows = items.length % $scope.columns !== 0 ? numRows + 1 : numRows;

                    for (var i = 0; i < numRows; i++) {
                        var row = items.slice(i * $scope.columns, (i + 1) * $scope.columns);
                        $scope.rows.push(row);
                    }

                });
            }
    };
  }]);
这也行得通,但它很尴尬,违反了德米特定律,这很重要,因为如果我将来改变它在内部的工作方式,它可能会破坏隐藏的内容。如何对此进行改进以避免此问题


.

使用委托模式。其思想是在指令中公开一个可定制的函数,并插入实际操作。该操作将在调用属于父作用域的函数的转移作用域内触发

<div grid="items" columns="3" custom-action="addHello"> //addHello() belongs to the DemoCtrl's scope 
    {{doAction(item) || 'Undefined'}} (name is {{item.name}}) //doAction() belongs to the translcuded scope
</div>

这不是违背了转换的整个思想,因为现在被转换的元素依赖于指令的范围。我只是想大声说出来。:)@基于这个用例,这是一个可能的解决方案,因为您必须接触两侧。最好的方法是使用委托模式来清晰地分离逻辑。我已经想到了这一点,如果您有一组有限的(和预期的)操作想要公开,它肯定会起作用。但是,如果我使此控件可重用,如果不进行分叉和修改以戳出所需操作的漏洞,此解决方案将无法运行。顺便问一下,您的帐户真的被黑客攻击了吗?还是它只是一个ID?…只是好奇…:)@仲哈,不,这是指
<!-- works, but ಠ_ಠ -->
<div grid="items" columns="3">
  {{$parent.$parent.$parent.$parent.addHello(item) || 'Undefined'}} (name is {{item.name}})
</div>
<div grid="items" columns="3" custom-action="addHello"> //addHello() belongs to the DemoCtrl's scope 
    {{doAction(item) || 'Undefined'}} (name is {{item.name}}) //doAction() belongs to the translcuded scope
</div>
scope: {
    ...
    customAction: "&"
},
link: function($scope, $el, $attrs) {

    ...

    $scope.doAction = function(item){
        return $scope.customAction(item);
    }
}