【问题标题】:How do I sort html tables in knockout using a Breeze navigation property?如何使用 Breeze 导航属性对淘汰赛中的 html 表格进行排序?
【发布时间】:2014-07-09 09:53:24
【问题描述】:

我正在使用 Breeze.js 将我的数据模型交给 Knockout.js,这是一个相当简单的视图模型来处理适配器库。我使用tablesorter 和这个敲除绑定处理程序对我的实体属性进行了排序:

ko.bindingHandlers.sort = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var asc = false;
        element.style.cursor = 'pointer';

        element.onclick = function () {
            var value = valueAccessor();
            var prop = value.prop;
            var data = value.arr;

            asc = !asc;
            if (asc) {
                data.sort(function (left, right) {
                    return left[prop]() === right[prop]() ? 0 : left[prop]() < right[prop]() ? -1 : 1;
                });
            } else {
                data.sort(function (left, right) {
                    return left[prop]() === right[prop]() ? 0 : left[prop]() > right[prop]() ? -1 : 1;
                });
            }
        };
    }
};

我正在扩展我的 Breeze 数据服务中的导航属性,它可以很好地将数据绑定到表中。

em.executeQuery(breeze.EntityQuery.from('SpecificAdapters').expand('Adapter'));

从 js 访问我的 EF 中的特定数据将是:specificAdapters()[0].Adapter().BoardName。像这样使用html:

<table class="tablesorter">
    <thead>
        <tr>
            <th data-bind="sort: {arr: specificAdapters, prop: 'Adapter().BoardName'}">Board Name</th>
            <th data-bind="sort: {arr: specificAdapters, prop: 'PbaNumber'}">Pba Number</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: specificAdapters">
        <tr>
            <td data-bind="text: Adapter().BoardName"></td>
            <td data-bind="text: PbaNumber"></td>
        </tr>
    </tbody>
</table>

我看到 Board Name 和 PBA Number 列都正确填充。 PBA 编号列对两个方向进行排序。显然,使用 Board Name 列进行排序时出现错误。

问题是,我该如何进行这项工作?

我不太了解绑定处理程序代码,无法知道要更改哪些内容才能使其适用于任何一种情况。我理解的其他解决方案将涉及扩展 Breeze 中的实体,例如

var store = em.metadataStore;
var SpecificAdapter = function () { this.BoardName = ko.observable(''); };
store.registerEntityTypeCtor('SpecificAdapter', SpecificAdapter);

然后在查询执行后运行一个循环以将 Board Name 重新映射到另一个实体。不过,这似乎是一个杂项,并且必须在我的整个应用程序中大量执行,其中对绑定处理程序的修复将是最好的解决方案。

感谢@awexfwex 的回答

我不得不稍微调整一下代码:ko.utils.unwrapObservable 是当前对展开的访问,leftProp[propNestings[i]] 实际上翻译了一个嵌套且尚未展开的属性,它会显示为@987654329 @。所以你必须在使用它来索引你的数组之前删除()

最终代码:

ko.bindingHandlers.sort = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var asc = false;
        element.style.cursor = 'pointer';

        element.onclick = function () {
            var value = valueAccessor();
            var prop = value.prop;
            var data = value.arr;

            var propNestings = prop.split(".");
            var propNestingsCount = propNestings.length;

            asc = !asc;
            if (asc) {
                data.sort(function (left, right) {
                    var leftProp = ko.utils.unwrapObservable(left);
                    var rightProp = ko.utils.unwrapObservable(right);
                    for (var i = 0; i < propNestingsCount; i++) {
                        leftProp = ko.utils.unwrapObservable(leftProp[propNestings[i].replace('()', '')]);
                        rightProp = ko.utils.unwrapObservable(rightProp[propNestings[i].replace('()', '')]);
                    }
                    return leftProp === rightProp ? 0 : leftProp < rightProp ? -1 : 1;
                });
            } else {
                data.sort(function (left, right) {
                    var leftProp = ko.utils.unwrapObservable(left);
                    var rightProp = ko.utils.unwrapObservable(right);
                    for (var i = 0; i < propNestingsCount; i++) {
                        leftProp = ko.utils.unwrapObservable(leftProp[propNestings[i].replace('()', '')]);
                        rightProp = ko.utils.unwrapObservable(rightProp[propNestings[i].replace('()', '')]);
                    }
                    return leftProp === rightProp ? 0 : leftProp > rightProp ? -1 : 1;
                });
            }
        };
    }
};

【问题讨论】:

    标签: javascript jquery html knockout.js breeze


    【解决方案1】:

    在您的排序函数中,它假设 sort 属性只是一个敲除 observable 的命名属性。您可以尝试递归展开它们,例如(未经测试):

        ko.bindingHandlers.sort = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            var asc = false;
            element.style.cursor = 'pointer';
    
            element.onclick = function () {
                var value = valueAccessor();
                var prop = value.prop;
                var data = value.arr;
    
                var propNestings = prop.split(".");
                var propNestingsCount = propNestings.length;
    
                asc = !asc;
                if (asc) {
                    data.sort(function (left, right) {
                        var leftProp = ko.unwrapObservable(left);
                        var rightProp = ko.unwrapObservable(right);
                        for (var i = 0; i < propNestingsCount; i++) {
                            leftProp = ko.unwrapObservable(leftProp[propNestings[i]]);
                            rightProp = ko.unwrapObservable(rightProp[propNestings[i]]);
                        }
                        return leftProp === rightProp ? 0 : leftProp < rightProp ? -1 : 1;
                    });
                } else {
                    data.sort(function (left, right) {
                        var leftProp = ko.unwrapObservable(left);
                        var rightProp = ko.unwrapObservable(right);
                        for (var i = 0; i < propNestingsCount; i++) {
                            leftProp = ko.unwrapObservable(leftProp[propNestings[i]]);
                            rightProp = ko.unwrapObservable(rightProp[propNestings[i]]);
                        }
                        return leftProp === rightProp ? 0 : leftProp > rightProp ? -1 : 1;
                    });
                }
            };
        }
    };
    

    【讨论】:

    • 是的,它假设命名属性,我对 JS 还很陌生,所以你刚刚列出的一些内容发生在我身上,但我不知道如何去做。谢谢你,我今晚会实施这个并回复你。
    • 这有效,我将完成/测试的代码添加到问题中。此外,ko.utils.unwrapObservable 是访问当前淘汰赛的正确区域。当将它们用作数组索引时,我还必须从 leftProprightProp 中删除“()”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    • 2017-11-04
    • 2013-01-23
    • 1970-01-01
    相关资源
    最近更新 更多