【问题标题】:Knockout Paging in MVC with Web API使用 Web API 在 MVC 中淘汰分页
【发布时间】:2014-03-23 10:53:40
【问题描述】:

我无法让这个代码进入页面。表的页面大小始终相同 - 从 Web API 调用返回的项目数。传入的参数将被忽略 (3)。此外,后退和前进按钮元素没有图标(icon-step-backward 和 icon-step-forward),但这对于页面大小来说是次要的。

HTML

<table class="table">
    <thead>
        <tr>
            <th data-column="LastName">Last Name</th>
            <th data-column="FirstName">First Name</th>
            <th data-column="EnrollmentDate">Enrollment Date</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: students">
        <tr>
            <td data-bind="text: LastName" />
            <td data-bind="text: FirstName" />
            <td data-bind="text: EnrollmentDate" />
        </tr>
    </tbody>

    <tfoot>
        <tr>
            <td>
                Number of items per page:
                <select id="pageSizeSelector" data-bind="value: pageSize">
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                    <option value="4">4</option>
                    <option value="5">5</option>
                    <option value="6">6</option>
                    <option value="7">7</option>
                    <option value="8">8</option>
                    <option value="9">9</option>
                    <option value="10">10</option>
                </select>
            </td>
            <td colspan="3">
                <button data-bind="click: previousPage" class="btn"><i class="icon-step-backward"></i></button>
                Page<label data-bind="text: currentPageIndex() + 1" class="badge"></label>
                <button data-bind="click: nextPage" class="btn"><i class="icon-step-forward"></i></button>
            </td>
        </tr>
    </tfoot>
</table>

淘汰赛和 JQUERY

<script type="text/javascript">

    var viewModel = function () {
        self = this;
        self.currentPage = ko.observable();
        self.pageSize = ko.observable(3);
        self.currentPageIndex = ko.observable(0);
        self.students = ko.observableArray();
        self.currentPage = ko.computed(function () {
            var pagesize = parseInt(self.pageSize(), 3),
            startIndex = pagesize * self.currentPageIndex(),
            endIndex = startIndex + pagesize;
            return self.students.slice(startIndex, endIndex);
        });

        self.nextPage = function () {
            if (((self.currentPageIndex() + 1) * self.pageSize()) < self.students().length) {
                self.currentPageIndex(self.currentPageIndex() + 1);
            }
            else {
                self.currentPageIndex(0);
            }
        }
        self.previousPage = function () {
            if (self.currentPageIndex() > 0) {
                self.currentPageIndex(self.currentPageIndex() - 1);
            }
            else {
                self.currentPageIndex((Math.ceil(self.students().length / self.pageSize())) - 1);
            }
        }
    }

    $(document).ready(function () {
        $.ajax({
            url: "http://localhost:12769/api/student",
            type: "GET"
        }).done(function (data) {
            var vm = new viewModel();
            vm.students(data);
            ko.applyBindings(vm);
        }).error(function (jqXHR, textStatus, errorThrown) {
            alert(jqXHR.responseText || textStatus);
        });
    });

</script>

从 Web API 返回的 JSON

[{"$id":"1","ID":1,"LastName":"Alexander","FirstMidName":"Carson","EnrollmentDate":"2005-09-01T00:00:00","Enrollments":[{"$id":"2","EnrollmentID":1,"CourseID":1050,"StudentID":1,"Grade":0,"Course":{"$id":"3","CourseID":1050,"Title":"Chemistry","Credits":3},"Student":{"$ref":"1"}},{"$id":"4","EnrollmentID":2,"CourseID":4022,"StudentID":1,"Grade":2,"Course":{"$id":"5","CourseID":4022,"Title":"Microeconomics","Credits":3},"Student":{"$ref":"1"}},{"$id":"6","EnrollmentID":3,"CourseID":4041,"StudentID":1,"Grade":1,"Course":{"$id":"7","CourseID":4041,"Title":"Macroeconomics","Credits":3},"Student":{"$ref":"1"}}]},{"$id":"8","ID":2,"LastName":"Alonso","FirstMidName":"Meredith","EnrollmentDate":"2002-09-01T00:00:00","Enrollments":[{"$id":"9","EnrollmentID":4,"CourseID":1045,"StudentID":2,"Grade":1,"Course":{"$id":"10","CourseID":1045,"Title":"Calculus","Credits":4},"Student":{"$ref":"8"}},{"$id":"11","EnrollmentID":5,"CourseID":3141,"StudentID":2,"Grade":4,"Course":{"$id":"12","CourseID":3141,"Title":"Trigonometry","Credits":4},"Student":{"$ref":"8"}},{"$id":"13","EnrollmentID":6,"CourseID":2021,"StudentID":2,"Grade":4,"Course":{"$id":"14","CourseID":2021,"Title":"Composition","Credits":3},"Student":{"$ref":"8"}}]},{"$id":"15","ID":3,"LastName":"Anand","FirstMidName":"Arturo","EnrollmentDate":"2003-09-01T00:00:00","Enrollments":[{"$id":"16","EnrollmentID":7,"CourseID":1050,"StudentID":3,"Grade":null,"Course":{"$ref":"3"},"Student":{"$ref":"15"}}]},{"$id":"17","ID":4,"LastName":"Barzdukas","FirstMidName":"Gytis","EnrollmentDate":"2002-09-01T00:00:00","Enrollments":[{"$id":"18","EnrollmentID":8,"CourseID":1050,"StudentID":4,"Grade":null,"Course":{"$ref":"3"},"Student":{"$ref":"17"}},{"$id":"19","EnrollmentID":9,"CourseID":4022,"StudentID":4,"Grade":4,"Course":{"$ref":"5"},"Student":{"$ref":"17"}}]},{"$id":"20","ID":5,"LastName":"Li","FirstMidName":"Yan","EnrollmentDate":"2002-09-01T00:00:00","Enrollments":[{"$id":"21","EnrollmentID":10,"CourseID":4041,"StudentID":5,"Grade":2,"Course":{"$ref":"7"},"Student":{"$ref":"20"}}]},{"$id":"22","ID":6,"LastName":"Justice","FirstMidName":"Peggy","EnrollmentDate":"2001-09-01T00:00:00","Enrollments":[{"$id":"23","EnrollmentID":11,"CourseID":1045,"StudentID":6,"Grade":null,"Course":{"$ref":"10"},"Student":{"$ref":"22"}}]},{"$id":"24","ID":7,"LastName":"Norman","FirstMidName":"Laura","EnrollmentDate":"2003-09-01T00:00:00","Enrollments":[{"$id":"25","EnrollmentID":12,"CourseID":3141,"StudentID":7,"Grade":0,"Course":{"$ref":"12"},"Student":{"$ref":"24"}}]},{"$id":"26","ID":8,"LastName":"Olivetto","FirstMidName":"Nino","EnrollmentDate":"2005-09-01T00:00:00","Enrollments":[]}]

【问题讨论】:

    标签: asp.net-mvc knockout.js asp.net-web-api


    【解决方案1】:

    它可能对您不起作用的一个原因是,您使用的是基数为 3 的 parseInt。因此,在您的 currentPage ko 计算中,var pagesize = parseInt(self.pageSize(), 3) 行将导致 NaN .请参阅MDN docs 了解更多信息。

    这是 KO 可观察数组的一个有用的分页扩展,它也会清理您的视图模型。有关工作示例,请参阅此 fiddle。在您的情况下,您的视图模型将只是

    var viewmodel = function(){
         var self = this;
         self.students = ko.observableArray().paged(3);
    }
    

    你的 HTML 应该是这样的:

    <table data-bind="foreach: students.pagedItems">
        <!-- normal data binding syntax here -->
    </table>
    

    还有一些分页控件。这些使用 Bootstrap 类,但让您了解如何使用它们:

    <ul class="pagination">
        <li data-bind="css: { disabled: students.currentPageIndex() === 0 }"><a href="#" data-bind="click: students.previousPage">&laquo;</a></li>
    </ul>
    <ul class="pagination" data-bind="foreach: students.allPages">
        <li data-bind="css: { active: pageNumber === ($root.students.currentPageIndex() + 1) }">
            <a href="#" data-bind="text: pageNumber, click: function() { $root.students.moveToPage(pageNumber-1); }"></a>
        </li>
    </ul>
    <ul class="pagination">
        <li data-bind="css: { disabled: students.currentPageIndex() === students.maxPageIndex() }"><a href="#" data-bind="click: students.nextPage">&raquo;</a></li>
    </ul>
    <br />
    <span data-bind="text: students.currentStatus"></span>
    

    这是扩展名。我还有第二个选项可以传入排序函数,但它是完全可选的。

    ko.observableArray.fn.paged = function (perPage, sortComparator) {
                var items = this;
    
                items.currentPage = ko.observable();
                items.pageSize = ko.observable(perPage);
                items.currentPageIndex = ko.observable(0);
    
                items.currentItemPage = ko.computed(function () {
                    var pagesize = parseInt(items.pageSize(), 10),
                        startIndex = pagesize * items.currentPageIndex(),
                        endIndex = startIndex + pagesize;
                    return this().slice(startIndex, endIndex);
                }, items);
    
                items.pagedItems = ko.computed(function () {
                    var size = parseInt(items.pageSize(), 10),
                        start = items.currentPageIndex() * size;
    
                    if (typeof (sortComparator) === "function") {
                        var sorted = this().sort(sortComparator);
                        return sorted.slice(start, start + size);
                    } else {
                        return this().slice(start, start + size);
                    }
    
    
                }, items);
    
                items.maxPageIndex = ko.computed(function () {
                    return Math.ceil(this().length / items.pageSize()) - 1;
                }, items);
    
                items.allPages = ko.computed(function () {
                    var pages = [];
                    for (var i = 0; i <= items.maxPageIndex() ; i++) {
                        pages.push({ pageNumber: (i + 1) });
                    }
                    return pages;
                }, items);
    
                items.currentStatus = ko.computed(function () {
                    var pagesize = parseInt(items.pageSize(), 10),
                        start = pagesize * items.currentPageIndex(),
                        end = start + pagesize;
    
                    if (items.currentPageIndex() === items.maxPageIndex()) end = this().length;
    
                    return 'Showing ' + (start + 1) + ' to ' + end + ' of ' + this().length;
                }, items);
    
                items.nextPage = function () {
                    if (((items.currentPageIndex() + 1) * items.pageSize()) < items().length) {
                        items.currentPageIndex(items.currentPageIndex() + 1);
                    } else {
                        items.currentPageIndex(0);
                    }
                };
    
                items.previousPage = function () {
                    if (items.currentPageIndex() > 0) {
                        items.currentPageIndex(items.currentPageIndex() - 1);
                    } else {
                        items.currentPageIndex((Math.ceil(items().length / items.pageSize())) - 1);
                    }
                };
    
                items.moveToPage = function (index) {
                    items.currentPageIndex(index);
                };
    
                return items;
            };
    

    【讨论】:

    • 我不确定 Radix 值是多少。我需要使用 parseInt 吗?我尝试了您的分机,并在表格中得到了正确的号码,但寻呼不起作用。这是因为我在 中有它并且数据绑定在 中吗?谢谢
    • 你会想要使用 10 的基数,所以parseInt(pagesize, 10)。如果您使用了我发布的代码,那么分页内容是否在&lt;tfoot&gt; 中并不重要。不过我通常不使用&lt;tfoot&gt;,所以我不能肯定。
    • 原来我在nextPage 和previousPage 函数中有一个不正确的this 引用。更新了我的答案,并发布了fiddle
    • @BigDaddy 你看到我贴的小提琴了吗?为你工作?
    • 谢谢,小提琴就像魅力一样,我可以让你的代码在我的项目中使用硬编码数据。但是,我无法使用我需要的 ajax 调用让它工作。我将 mapping.fromJS 移到了 .done 回调中,但没有任何帮助。我也看不到您创建的学生类在哪里使用。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签