AngularJS:指令隔离范围

时间:2014-07-08 17:03:31

标签: angularjs angularjs-directive angularjs-scope

我正在开发一个表格的AngularJS指令。父控制ng-table需要为其选项和模型设置一个独立的范围。

但是,孩子们应该“继承”这个范围,这样你就不必将大量选项传递给一组非常相互关联的组件。

例如:

 <div ng-table="tableOptions" ng-model="results">

    <div ng-table-header>
        <div ng-table-header-column="column" 
             ng-repeat="column in tableOptions.columns">
            {{column.name}}
        </div>
    </div>

    <div ng-table-body>

        <div ng-table-row="row"
             ng-repeat="row in $results">

            <div ng-table-cell="column"
                 ng-repeat="column in tableOptions.columns">

                {{row[column.id]}}

            </div>
        </div>

    </div>
    <div ng-table-footer></div>
</div>

在上面的示例中,ng-table-headerng-header-column等都需要访问父控件ng-table中的属性。此外,所有指令replacetransclude

我知道我可以向子/父指令发送broadcast个事件,但是有更好的方法来限制父级别的范围并自动将其传递给子级吗?

2 个答案:

答案 0 :(得分:1)

哦伙计,你强迫我看看表格和输入指令是如何用角度来实现的。

因此,angularjs与您想要实现的内容类似 - ng-form 指令 ng-input

当您使用formng-form指令时,它会创建控制器(指令可以执行此操作)并转换html代码将继承它。 ng-inputinput)在require选项中要求提供。

require: ['ngModel', '^?form', '^?ngModelOptions'],

所以你在link函数中得到了这个控制器。所以...你可以调用函数,做事,你知道。

你可以这样做(只是一个想法,这是它的工作原理):

.directive('coolTable', function() {
  return {
    ...
    controller: function($scope) {
        $scope.columns = [];  /* Here you will have all table columns, so you can send it's data to service and do any work */
        $scope.registerColumn = function(column) {
            $scope.columns.push(column);
        };
    },
    ...
  };
})


.directive('column', function() {
  return {
    ...
    require: '^?coolTable',
    ...
    link: function(scope, element, attrs, coolTable) {
        coolTable.registerColumn(this);
    },
  };
})


<coolTable>
    <column></column>
    <column></column>
    <column></column>
</coolTable>

答案 1 :(得分:0)

我能够找到一个工作来查看创建自己的transclude指令以应用范围的angular-ui代码。

所以我的主table指令开始如下:

module.directive('ngTable', function ($rootScope, $timeout, $window, $compile) {
    return {
        restrict: 'AE',
        transclude: true, // NOTE THIS
        replace: true, // NOTE THIS
        templateUrl: 'common/components/table/views/table.tpl.html',
        scope: {
            ngModel: "=",
            tableOptions: "=ngTable"
        },
        controller: 'ngTableCtrl',
        link: function ($scope, $element, $attributes, controller, ngModel) {
            ....
        }
     }
});

然后我创建了自己的transclude指令,如:

module.directive('tableTransclude', function () {
    return {
        link: function ($scope, $element, $attrs, controller, $transclude) {
            $transclude($scope, function (clone) {
                $element.empty();
                $element.append(clone);
            });
        }
    };
})

表格模板中的用法如下:

<div table-transclude />

并且presto !!!有点hacky但完成工作。我理解为什么Angular会这样做,但在某些情况下你需要这种类型的范围。