使用映射时Knockout.js attr绑定已损坏

时间:2014-08-25 11:01:30

标签: javascript jquery knockout.js

我试图通过映射插件更新ViewModel,点击WebApi Controller发送的数据。在第一次加载时,一切正常,但是当数据更新时,绑定会被破坏。 我确实尝试将attr绑定更改为文本绑定并且它正在工作,所以我认为问题在于attr绑定。所以这是JS:

<script>
    function viewModel() {
        var self = this;
        self.currentPage = ko.observable();
        self.pageSize = ko.observable(10);
        self.currentPageIndex = ko.observable(0);
        self.jobs = ko.observableArray();
        self.currentPage = ko.computed(function () {
            var pagesize = parseInt(self.pageSize(), 10),
            startIndex = pagesize * self.currentPageIndex(),
            endIndex = startIndex + pagesize;
            return self.jobs.slice(startIndex, endIndex);
        });
        self.nextPage = function () {
            if (((self.currentPageIndex() + 1) * self.pageSize()) < self.jobs().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.jobs().length / self.pageSize())) - 1);
            }
        }
        self.sortType = "ascending";
        self.sortTable = function (viewModel, e) {
            var orderProp = $(e.target).attr("data-column")
            self.jobs.sort(function (left, right) {
                leftVal = left[orderProp];
                rightVal = right[orderProp];
                if (self.sortType == "ascending") {
                    return leftVal < rightVal ? 1 : -1;
                }
                else {
                    return leftVal > rightVal ? 1 : -1;
                }
            });
            self.sortType = (self.sortType == "ascending") ? "descending" : "ascending";
        }
        // Here is function that must update ViewModel
        self.getDays = function (days) {
            var uri = "/api/job?days=" + days;
            $.getJSON(uri, function (data) {
                ko.mapping.fromJS(data.$values, {}, self.jobs);
            })
            .error(function (xhr, status, error) {
                var err = eval("(" + xhr.responseText + ")");
                alert(err.Message);
            });
        }
        $.getJSON("/api/job", function (data) {
            self.jobs(data.$values);
        });
    }
    $(document).ready(function () {
        ko.applyBindings(new viewModel());
    });
</script>

这就是我呼吁更新的方式。

<div class="btn-group">
            <button type="button" class="btn btn-default" id="7" value="7" data-bind="click: getDays.bind($data, '7')">7 дней</button>
            <button type="button" class="btn btn-default" id="10" value="10" data-bind="click: getDays.bind($data, '10')">10 дней</button>
            <button type="button" class="btn btn-default" id="14" value="14" data-bind="click: getDays.bind($data, '14')">14 дней</button>
            <button type="button" class="btn btn-default" id="30" value="30" data-bind="click: getDays.bind($data, '30')">30 дней</button>
            <button type="button" class="btn btn-default" id="60" value="60" data-bind="click: getDays.bind($data, '60')">60 дней</button>
            <button type="button" class="btn btn-default" id="180" value="180" data-bind="click: getDays.bind($data, '180')">180 дней</button>
        </div>

这是提供数据的表格。

<table id="arrival" class="table table-condensed table-striped">
        <thead>
            <tr data-bind="click: sortTable">
                <th></th>
                <th data-column="excursion">Название</th>
                <th data-column="excursiondate">Дата</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: currentPage">
            <tr>
                <td><a data-bind="attr: { href: '/list/' + $data.kodg }" target="_parent">Список туристов</a></td>
                <%--<td data-bind="text: $data.kodg""></td>--%>
                <td data-bind="text: $data.excursion"></td>
                <td data-bind="text: $data.excursiondate"></td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td colspan="3" class="pager">
                    <button data-bind="click: previousPage" class="btn previous"><i class="glyphicon glyphicon-backward"></i></button>
                    Страница
                            <label data-bind="text: currentPageIndex() + 1" class="badge"></label>
                    <button data-bind="click: nextPage" class="btn next"><i class="glyphicon glyphicon-forward"></i></button>
                </td>
            </tr>
        </tfoot>
    </table>

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

Knockout映射会将所有属性转换为observable。因此,在您的attr绑定中,kodg属性是一个函数(ko.observable实例),您应该进行以下更改:

attr: { href: '/list/' + ko.utils.unwrapObservable($data.kodg) }

或只是

attr: { href: '/list/' + $data.kodg() }

如果kodg总是可以观察到的。

答案 1 :(得分:0)

试试这个

<a 
    data-bind="
        attr: { href: $parent.Link($data.kodg) }" 
    target="_parent">
    Список туристов
</a>

在你的viewmodel中

self.Link = function(data){
    return '/list/' + data
   // Or if you have observable return '/list/' + data()
}