AngularJS:自定义指令不适用于 dirPagination

AngularJS: Custom directives not working with dirPagination

我正在使用 AngularJS 创建一个页面,其中包含一个产品列表,显示名称、价格、区域等信息。这显示有点像手风琴,名称在 header 和 body 中的额外信息。

由于可能会显示大量这些项目,因此我使用 dirPagination (https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination) 对这些项目进行分页。我现在的标记如下所示:

<div class="custom-list" dir-paginate="asset in assets | itemsPerPage: 10 track by $index">
    <div class="custom-list-item" ng-class="{'tag-hover': isHoveredTag(asset)}">
        <div class="custom-list-item-heading" ng-click="toggleShowAssetDetails(asset)">
            <p class="col-lg-5">{{ asset.name }}</p>
            <div class="col-lg-offset-2 col-lg-3 rating">
                <rating value="asset.rating" />
            </div>
            <button ng-click="addAsset(asset)"><span class="glyphicon glyphicon-plus"></span></button>
            <div class="clearfix"></div>
        </div>
        <div class="custom-list-item-content" style="display: none" animate="shouldShowAssetDetails(asset)">
            ...
        </div>
    </div>
</div>

如您所见,我正在以一种非常标准的方式使用分页,只是循环遍历数组中的项目并每页显示 10 个。我还有一个名为 rating 的指令,它查看项目中名为 rating 的值。这是一个 1 - 5 的数字,用于在名称旁边显示星级系统。该指令如下所示:

var rating = function ($compile) {
    return {
        restrict: "E",
        scope: {
            value: "="
        },
        link: function (scope, element, attrs) {
            scope.$watch(attrs.rating, function () {
                for (var i = 1; i <= 5; i++) {
                    if (i <= scope.value) {
                        var starElement = angular.element("<span class=\"icon icon-crown\"></span>");
                        $compile(starElement)(scope);
                        element.append(starElement);
                    } else {
                        var emptyStarElement = angular.element("<span class=\"icon-empty icon-crown\"></span>");
                        $compile(emptyStarElement)(scope);
                        element.append(emptyStarElement);
                    }
                }
            })            
        }
    }
}

这会查看值并根据评级值插入图标(例如,如果评级为 2,指令将插入两个 icon-crown 图标范围和 3 icon-empty icon-crown 图标跨度。

在我包含分页之前,这工作得很好。但是现在它只适用于前 10 个项目。当您更改页面时,评级不会改变,只会保留与上一页相同的图标,即使值不同也是如此。

我知道这是因为该指令在开始时设置了所有内容,当您更改页面时它不会 运行 因为项目不会重新加载它们只是再次显示和隐藏。但是该指令正在操纵 DOM,因此它不会在页面更改时更新。

问题是我不知道如何解决这个问题。我考虑过更改指令以查找分页当前页面,但后来我无权访问当前列表项。

对于在页面更改时获取更新图标的指令的任何帮助,我将不胜感激。

更新 这是一个 Plunker 项目的 link,显示了我遇到的问题:http://plnkr.co/edit/VSQ20eWCwVpaCoS7SeQq?p=preview

这是我遇到问题的应用程序部分的精简版。尽管我保留了 CSS class 结构,但没有包含任何样式。我还更改了图标以使用 bootstrap 图标来简化 Plunker 项目。

但是功能是一样的。如果您从第 1 页转到第 2 页,请注意尽管资产评级值不同,但星星如何保持不变。但是,如果您转到第 3 页并返回第 2 页或第 1 页,它们将会改变。发生这种情况的原因是因为第 3 页上的项目较少,因此当您返回第 1 或 2 页时,将再次调用剩余的项目以检索评分值。

您只需删除或替换 track by $index

$index 的跟踪会给您带来以下行为:

有一个最大长度为 10 的数组,表示要显示的项目。第一项的索引为 0。

您转到下一页,数组中的项目被替换。

数组中的第一项仍将具有索引 0。由于您正在按索引跟踪并且索引未更改,因此 AngularJS 将不会重新创建表示该项目的 DOM 节点。由于未重新创建 DOM 节点,因此这次指令不会执行,评级也不会更新。

如果从第 3 页转到第 2 页,指令将执行第 2 页的最后 7 个元素,因为它们在第 3 页不存在,所以这次它们被认为是新的。

如果你真的需要使用track by,你应该使用与对象实际相关(且唯一)的属性,例如:

dir-paginate="asset in assets | itemsPerPage: 10 track by asset.name"

演示: http://plnkr.co/edit/A80tSEliUkG5idBmGe3B?p=preview