我正在使用AngularJS创建一个页面,其中包含显示名称,价格,区域等信息的产品列表。这类似于手风琴,标题中包含名称,而且正文中有额外信息。
由于可能会显示大量这些项目,因此我使用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>
正如您所看到的,我正在以非常标准的方式使用paginate,只需循环遍历数组中的项目并每页显示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,则指令将插入两个图标 - 图标图标跨度和3个图标 - 空图标 - 图标图标跨度。
在我加入分页之前,这完全正常。但是现在它只适用于前10个项目。当您更改页面时,即使值不同,评级也不会更改,只保留上一页中的相同图标。
我理解这是因为该指令在开始时设置了所有内容,当您更改页面时它不会运行,因为项目没有重新加载它们只是被显示和再次隐藏。但该指令正在操纵DOM,因此在页面更改时它不会更新。
问题是我不知道如何解决这个问题。我想改变指令来寻找分页当前页面,但后来我无法访问当前列表项。
我很感激在页面更改时获取指令更新图标的任何帮助。
更新 这是一个Plunker项目的链接,显示了我遇到的问题:http://plnkr.co/edit/VSQ20eWCwVpaCoS7SeQq?p=preview
这是我的应用程序部分的一个非常精简的版本,我遇到了问题。虽然我保留了CSS类结构,但没有包含样式。我还将图标更改为使用bootstrap,以简化Plunker项目。
但功能相同。如果从第1页到第2页,请注意尽管资产评级值不同,但恒星仍保持不变。但是,如果您转到第3页并返回第2页或第1页,它们将会更改。发生这种情况的原因是因为第3页上的项目较少,因此当您返回第1页或第2页时,将再次调用剩余项目以检索评级值。
答案 0 :(得分:1)
您只需删除或替换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"