【问题标题】:Angular Directive that uses same model, but different data使用相同模型但数据不同的 Angular 指令
【发布时间】:2014-07-25 20:46:30
【问题描述】:

我正在尝试为页面上 2 个位置存在的分页创建自定义指令。我有 2 个数据表,我想使用相同的分页指令。这是我的指令

app.directive('pagination', function () {
        return {

            restrict: 'A',
            template: '<div ng-if="!isLoading" class="backup-pagination">\
                        <input type="button" ng-disabled="currentPage == 0" ng-click="currentPage = currentPage - 1" value="Prev" />\
                        <span>{{ currentPage+1 }} / {{ numberOfPages(backupList) }}</span>\
                        <input type="button" ng-disabled="currentPage >= backupList.length/pageSize - 1" ng-click="currentPage = currentPage + 1" value="Next" />\
                    </div>',
            scope : {
                currentPage: '=',
                backupList: '='
            },
            link: function(scope, elem, attrs){

            }
        }
    });

这里是 DOM

这是表格的一个分页指令

<div ng-if="!isLoading" pagination backup-type="active" current-page="ActiveCurrentPage" backup-list="data.ActiveBackups"></div>

这是另一张桌子的另一张

<div ng-if="!isLoading" pagination backup-type="inactive" current-page="InactiveCurrentPage" backup-list="data.InactiveBackups"></div>

问题是我的分页指令似乎无法访问控制器的父范围。似乎存在于控制器$scope 上的numberOfPages() 没有被调用。与pageSize 相同。我必须做些什么才能使我的所有应用程序都可以使用这个 1 指令,使用不同的数据集?

HTML

<div id="active-backups" class="backup-table-wrap">
            <h3>Active Backups</h3>
            <table id="active-backups-table" class="backup-table">
                <thead>
                    <tr>
                        <th>Customer</th>
                        <th>Last Archived</th>
                        <th>Archive Size (GB)</th>
                        <th>Mailboxes</th>
                        <th>Items</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody ng-if="isLoading">
                    <tr load-spinner></tr>
                </tbody>

                <tbody  ng-if="!isLoading">
                    <tr ng-repeat="active in data.ActiveBackups | paginate:ActiveCurrentPage*pageSize | limitTo:pageSize">
                        <td><a ui-sref="order.overview({ orderId: active.ServiceId })" ng-click="select(active)">{{ active.Customer }}</a></td>
                        <td>{{ active.LastArchived }}</td>
                        <td>{{ active.ArchiveSizeGB | number:2 }}</td>
                        <td>{{ active.NumMailboxes }}</td>
                        <td>{{ active.ArchivedItems }}</td>
                        <td><input type="button" class="backup-restore-btn" value="Restore" /></td>
                    </tr>
                </tbody>
            </table>
            <div ng-if="!isLoading" pagination backup-type="active" current-page="ActiveCurrentPage" backup-list="data.ActiveBackups"></div>

        </div>


        <div id="inactive-backups" class="backup-table-wrap">
            <h3>Inactive Backups</h3>
            <table id="inactive-backups-table" class="backup-table">
                <thead>
                    <tr>
                        <th>Customer</th>
                        <th>Last Archived</th>
                        <th>Archive Size (GB)</th>
                        <th>Mailboxes</th>
                        <th>Items</th>
                        <th></th>
                    </tr>
                </thead>
                 <tbody ng-if="isLoading">
                    <tr load-spinner></tr>
                </tbody>

                <tbody  ng-if="!isLoading">
                    <tr ng-repeat="active in data.InactiveBackups | paginate:InactiveCurrentPage*pageSize | limitTo:pageSize">
                        <td><a href="#">{{ active.Customer }}</a></td>
                        <td>{{ active.LastArchived }}</td>
                        <td>{{ active.ArchiveSizeGB | number:2 }}</td>
                        <td>{{ active.NumMailboxes }}</td>
                        <td>{{ active.ArchivedItems }}</td>
                        <td><input type="button" class="backup-restore-btn" value="Restore" /></td>
                    </tr>
                </tbody>
            </table>
                <div ng-if="!isLoading" pagination backup-type="inactive" current-page="InactiveCurrentPage" backup-list="data.InactiveBackups"></div>


        </div>

【问题讨论】:

  • 您已经使用指令创建了一个新范围。如果要使用父范围,则必须传入函数或使用 $parent.numberOfPages(backupList)

标签: angularjs pagination


【解决方案1】:

那是因为您在指令上声明了一个隔离范围,这意味着它不会继承控制器的父 $scope 并且每次创建它时都会创建一个新的。您可以保持隔离范围并在该范围内传递指令的其他要求,而不是依赖于通过继承从父控制器获取它,IMO 这种方法更加清晰和明确。

 scope : {
           currentPage: '=',
           backupList: '=',
           numberOfPages: '&'
         },

然后像这样传入函数:

<div ng-if="!isLoading" pagination backup-type="inactive" current-page="InactiveCurrentPage" backup-list="data.InactiveBackups" number-of-pages="numberOfPages()"></div>

【讨论】:

  • 这是有道理的,但是,如果我的每一个分页指令都使用相同的“numberOfPages”,不应该有更好的方法来调用该函数来减少代码冗余
  • 例如,不必在每个分页指令上加上 number-of-pages="numberOfPages()" ,我可以在链接函数中执行 scope.$parent.numberofPages()
  • 这是一个很好的观点,对此我没有很好的答案。它可能看起来像代码冗余,但是当您仔细考虑时,通过在每个指令减速中提供该功能并没有真正引起维护问题。您可能会在页面上包含其中的一两个,如果更多,您会将指令声明代码放在 ng-repeat 中,这会使重复不那么明显。编辑:你可以这样做,但我更喜欢再次传递该函数而不是执行 scope.$parent。我的意思是,如果您在另一个页面中使用该指令,则需要确保
  • numberOfPages 存在于该页面的控制器$scope 上,但是当您在视图模板中明确定义对mumber-of-pages 的需求时,您会使其指令需要@ 更加清晰和明确987654328@。与这种隐式依赖相比,我倾向于更多的代码重复。
  • 从我的观点来看,您有两个选择:将您要使用的每条数据传递到您的指令中(显式::好),或者不创建新范围并搭载您的父母(隐含的::丑陋的)。
【解决方案2】:

我现在找到了解决方法,但我真的很想弄清楚如何以正确的方式做到这一点。我所做的是向这样的指令发送回调函数:

<div ng-if="!isLoading" pagination backup-type="active" on-change="onPageChange" backup-list="data.ActiveBackups"></div>

其中onPageChange 是我的控制器$scope 上的回调函数。接下来,我将页面更改连接起来,以便在每次页面更改时调用该回调函数

scope.nextPage = function () {

     scope.currentPage++;
     scope.onChange(scope.currentPage, attrs.backupType);

}

然后我像这样在$scope 上设置回调

$scope.onPageChange = function (newPage, type) {
            console.log(newPage);
            if (type == 'active') {
                $scope.ActiveCurrentPage = newPage;
            } else {
                $scope.InactiveCurrentPage = newPage;
            }
        }

这解决了我的问题,但感觉不是“正确”的方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多