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

标签 javascript angularjs angularjs-directive pagination dirpagination

我正在使用 AngularJS 创建一个页面,其中包含显示名称、价格、区域等信息的产品列表。这显示得有点像 Accordion ,名称在标题中,额外信息在正文中。

由于可能会显示大量这些项目,因此我使用 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,则指令将插入两个图标-皇冠图标跨度和 3 个图标-空图标-皇冠图标跨度。

在我添加分页之前,它工作得非常好。但现在它仅适用于前 10 项。当您更改页面时,即使值不同,评级也不会改变,只是保留与上一页相同的图标。

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

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

如果您能在页面更改时获取更新图标的指令,我将不胜感激。

更新 以下是 Plunker 项目的链接,显示了我遇到的问题:http://plnkr.co/edit/VSQ20eWCwVpaCoS7SeQq?p=preview

这是我遇到问题的应用程序部分的一个非常精简的版本。尽管我保留了 CSS 类结构,但不包含样式。我还更改了图标以使用 Bootstrap 图标,只是为了简化 Plunker 项目。

但是功能是相同的。如果您从第 1 页翻到第 2 页,请注意尽管 Assets 评级值不同,但星星仍然保持不变。但是,如果您转到第 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

关于javascript - AngularJS:自定义指令不适用于 dirPagination,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28474483/

相关文章:

javascript - 使用 KeystoneJS CMS 为 AngularJS 应用程序生成 html 文件

html - 部分只读文本框

javascript - 通过属性获取MongoDB中存储的数组

javascript - 使用来自 ajax 或 jquery.get() 的数据打印 div

javascript - 在使用 Angular JS 进行模板化时使用辅助方法

javascript - 你能用 Angular 压缩 get 请求的内容吗?

javascript - 弹出后禁用所有文本框

javascript - 从 Angularjs 中的 View 触发模型更新

angularjs - 为 jQuery UI 按钮创建 AngularJS 指令

javascript - Angular JS 级联通知