Pregunta

enter image description here

Why the foreach binding in the pagination is rendering the same page number two times?

I have only one object in the array allPagesPosition and still it renders two times.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js">
</script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js">
</script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js">
</script>
<script type="text/javascript">
    var PositionModel = function (data) {
        console.log('mouse');
        ////////debugger;
        var self = this;

        self.PositionSortDescending = -1;

        self.listPosition = ko.mapping.fromJS(data);
        console.log(self.listPosition()[0].Id());
        if (self.listPosition == undefined) {
            self.listPosition = ko.observableArray();
        }
        self.pageSizePosition = ko.observable(10);
        self.pageIndexPosition = ko.observable(0);
        self.selectedItemPosition = ko.observable();
        self.positionToEdit = ko.observable();



        self.sortPosition = function (item) {
            //debugger;
            self.listPosition.sort(function (a, b) {
                //debugger;
                var aID = a.Name();
                var bID = b.Name();
                return (aID == bID) ? 0 : (aID > bID) ? self.PositionSortDescending : -self.PositionSortDescending;
            });
            self.PositionSortDescending = -self.PositionSortDescending;
            self.listPosition.valueHasMutated();
        };

        self.addPosition = function () {
            ////debugger;
            var newItem = ko.mapping.fromJS({
                Id: 0,
                Name: ''
            });
            //data.splice(0, 0, newItem); //index, homManyToRemove, elementsToAdd [e1, e2, ... ]
            //self.listPosition().push(newItem);
            //ko.mapping.fromJS(data, self.listPosition);
            self.listPosition.splice(0, 0, newItem);
            self.listPosition.valueHasMutated();
            self.moveToPagePosition(self.maxPageIndexPosition());
            self.positionToEdit(newItem);
            $('#txtPositionName').focus();
            //////debugger;
        };

        self.savePosition = function () {
            ////debugger;
            var item = self.positionToEdit();
            $.ajax({
                url: "../api/userApi/SavePosition",
                type: "POST",
                data: ko.toJSON(item),
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                success: function (data) {
                    ////debugger;
                    if (data != null) {
                        item.Id(data.Id);
                    }
                }
            });
            self.positionToEdit(null);
        };

        self.cancelSavingPosition = function () {
            ////////debugger;
            self.positionToEdit(null);
        }

        self.removePosition = function (item) {
            //debugger;
            if (item.Id) {
                if (confirm('Are you sure you wish to delete this item?')) {
                    self.listPosition.remove(item);
                    $.ajax({
                        url: "../api/userApi/DeletePosition",
                        data: ko.toJSON(item),
                        type: "DELETE",
                        contentType: 'application/json; charset=utf-8',
                        dataType: 'json',
                        success: function (data) {
                            //debugger;
                        }
                    });
                    if (self.pageIndexPosition() > self.maxPageIndexPosition()) {
                        self.moveToPagePosition(self.maxPageIndexPosition());
                    }
                }
            } else {
                self.listPosition().remove(item);
                if (self.pageIndexPosition() > self.maxPageIndexPosition()) {
                    self.moveToPagePosition(self.maxPageIndexPosition());
                }
            }
        }

        self.selectPosition = function (item) {
            ////////debugger;
            self.selectedItemPosition(item);
        }

        self.templateToUsePosition = function (item) {
            //////debugger;
            console.log(item.Name());
            var compare = self.positionToEdit();
            var str = compare === item ? 'editTmplPosition' : 'itemsTmplPosition';
            //debugger;
            return str;
        };

        self.editPosition = function (item) {
            ////////debugger;
            self.positionToEdit(item);
        };

        self.pagedListPosition = ko.dependentObservable(function () {
            //////debugger;
            var size = self.pageSizePosition();
            var start = self.pageIndexPosition() * size;
            var list = self.listPosition.slice(start, start + size);
            //////debugger;
            return list;
        });

        self.maxPageIndexPosition = ko.dependentObservable(function () {
            //////debugger;
            var maxPageIndex = Math.ceil(self.listPosition().length / self.pageSizePosition()) - 1;
            console.log('page index = ' + maxPageIndex);
            return maxPageIndex;
        });

        self.previousPagePosition = function () {
            ////////debugger;
            if (self.pageIndexPosition() > 0) {
                self.pageIndexPosition(self.pageIndexPosition() - 1);
            }
        };

        self.nextPagePosition = function () {
            ////////debugger;
            if (self.pageIndexPosition() < self.maxPageIndexPosition()) {
                self.pageIndexPosition(self.pageIndexPosition() + 1);
            }
        };

        self.allPagesPosition = ko.dependentObservable(function () {
            ////////debugger;
            var pages = [];
            for (i = 0; i <= self.maxPageIndexPosition() ; i++) {
                console.log('page-' + i);
                pages.push({
                    pageNumber: (i + 1)
                });
            }
            return pages;
        });

        self.moveToPagePosition = function (index) {
            //////debugger;
            self.pageIndexPosition(index);
        };


    };

    $(function () {

        ko.applyBindings(new PositionModel([{
            Id: 1,
            Name: 'abc'
        }, { Id: 2, Name: 'def' }]));

    });
</script>
<div id="abcd">
    <div>

        <table  style="width: 400px">
            <p>
                <a  data-bind="click: addPosition" href="#" title="edit">Add</a>
            </p>

            <thead>
                <tr>
                    <th>
                        <a href="#" data-bind="click: sortPosition" >position</a>
                    </th>
                    <th style="width: 100px; text-align: right;" />
                </tr>
            </thead>
            <tbody data-bind="template: { name: templateToUsePosition, foreach: pagedListPosition }" />
        </table>

        <div >
            <ul>
                <li data-bind="css: { disabled: pageIndexPosition() === 0 }">
                    <a href="#" data-bind="click: previousPagePosition" >previous</a>
                </li>
            </ul>
            <div data-bind="text: ko.toJSON(allPagesPosition)"></div>
            <ul data-bind="foreach: allPagesPosition">
                <li data-bind="css: { active: $data.pageNumber === ($parent.pageIndexPosition() + 1) }">
                    <a href="#" data-bind="text: $data.pageNumber, click: function () { $parent.moveToPagePosition($data.pageNumber - 1); }" />
                </li>
            </ul>
            <ul>
                <li data-bind="css: { disabled: pageIndexPosition() === maxPageIndexPosition() }">
                    <a href="#" data-bind="click: nextPagePosition" >next</a>
                </li>
            </ul>
        </div>

        <script id="itemsTmplPosition" type="text/html">
            <tr style="width: auto" data-bind="click: $parent.selectPosition, css: { 'info': $data === $parent.selectedItemPosition() }">
                <td style="width: auto" data-bind="text: Name" />
                <td  style="width: 200px">
                    <a  data-bind="click: $parent.editPosition" href="#" title="edit">
                        <i  />
                    </a>
                    <a  data-bind="click: $parent.removePosition" href="#" title="remove">
                        <i  />
                    </a>
                </td>
            </tr>
        </script>
        <script id="editTmplPosition" type="text/html">
            <tr>
                <td>
                    <input style="width: auto" id="txtPositionName" data-bind="value: Name" />
                </td>
                <td >
                    <a  data-bind="click: $parent.savePosition" href="#" title="save">
                        <i  />
                    </a>
                    <a  data-bind="click: $parent.cancelSavingPosition" href="#" title="cancel">
                        <i  />
                    </a>
                </td>
            </tr>
        </script>

    </div>
</div>
¿Fue útil?

Solución

a elements cannot be self closed. This leads to invalid HTML markup which confuses Knockout.

To fix it you just need to correctly close your a element in your allPagesPosition list:

<ul data-bind="foreach: allPagesPosition">
    <li> 
        <a href="#" data-bind="text: $data.pageNumber"></a>
    </li>
</ul>

Demo JSFiddle.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top