7

我所有的指令都使用相同的范围,我希望我的指令能够自己操作。

指示:

app.directive('headerSort', function () {
    return {
        restrict: 'A',
        controller: function ($scope, $element, $attrs) {
            $scope.caption = $attrs.caption;

            $scope.doSort = function () {
                $scope.orderField = $attrs.headerSort;
                $scope.reverse = !$scope.reverse;
            };
        },
        template: '<div data-ng-click="doSort();">' +
                    '{{caption}}' +
                    '<i class="icon-sort"></i>' +
                  '</div>'
    };
});

html:

<th data-header-Sort="FullName" data-caption="Full name"></th>
<th data-header-Sort="FirsName" data-caption="First name"></th>
<th data-header-Sort="Age" data-caption="Age"></th>

结果是所有列都具有值“年龄”并按年龄排序。我当然希望每一列都排序它自己的列。我怎样才能做到这一点?

更新:忘记提及orderFieldreverse用于ng-repeat | orderBy

<tbody id="customerRows" data-ng-repeat="customer in customers | orderBy:orderField:reverse">
4

2 回答 2

11

指令的每个实例都需要有自己的标题、排序类型和反向属性。因此该指令将需要它自己的(子)范围——隔离范围(scope: {})或新范围(scope: true)。由于指令不是独立/自包含的组件,我不会使用隔离范围(另请参阅在 AngularJS 中编写指令时,我如何决定是否需要新的范围、新的子范围或新的隔离范围?)。

使用为指令选择的范围类型,排序类型和反向值可以通过函数参数传递给父级,也可以直接在父级范围上设置。我建议函数参数:

app.directive('headerSort', function () {
    return {
        scope: true,   // creates a new child scope
        link: function (scope, element, attrs) {
            scope.caption  = attrs.caption;
            scope.sortType = attrs.headerSort;
            scope.reverse  = false;
        },
        template: '<div data-ng-click="reverse=!reverse; doSort(sortType, reverse);">' +
             '{{caption}}</div>'
    };
});
function MyCtrl($scope) {
    $scope.orderField = "FirstName";
    $scope.reverse    = false;
    $scope.customers  = [ {FirstName: 'Martijn', Age: 22}, {FirstName: 'Mark', Age: 44}];
    $scope.doSort = function (sortType, reverse) {
        console.log('sorting',sortType, reverse);
        $scope.orderField = sortType;
        $scope.reverse    = reverse;
    };
}
<table>
    <th data-header-sort="FirstName" data-caption="First name"></th>
    <th data-header-sort="Age" data-caption="Age"></th>
    <tbody id="customerRows" data-ng-repeat="customer in customers | orderBy:orderField:reverse">
        <tr><td>{{customer.FirstName}}<td>{{customer.Age}}
    </tbody>
</table>

fiddle 在小提琴中,为了简单起见,我没有包括 FullName 列。

于 2013-05-31T15:28:26.677 回答
1

您需要“隔离”您的范围。这将为指令的每个实例提供自己的范围。将以下内容添加到您的指令定义中:

scope: {},

因此,您的最终指令定义如下所示:

app.directive('headerSort', function () {
    return {
        restrict: 'A',
        scope: {},
        controller: function ($scope, $element, $attrs) {
            $scope.caption = $attrs.caption;

            $scope.doSort = function () {
                $scope.orderField = $attrs.headerSort;
                $scope.reverse = !$scope.reverse;
            };
        },
        template: '<div data-ng-click="doSort();">' +
                    '{{caption}}' +
                    '<i class="icon-sort"></i>' +
                  '</div>'
    };
});

Egghead.io 视频深入介绍了范围隔离。你可以在这里查看它们:http ://www.egghead.io/

隔离范围视频从教程 #16 开始。

于 2013-05-31T13:54:08.197 回答