Knockout.js按钮点击更新ViewModel

and*_*dko 4 javascript jquery mvvm knockout.js

好吧,那不是最好的情况说明......无论如何,我正在尝试更新我的ViewModel,但它无法正常工作.默认情况下,我从控制器功能和按钮单击 - 从同一个控制器中的另一个函数获取数据,但ViewModel仅包含在第一次ViewModel初始化后收到的数据.

<script>
     function viewModel () {
        var self = this;
        self.currentPage = ko.observable();
        self.pageSize = ko.observable(10);
        self.currentPageIndex = ko.observable(0);
        self.salesdata = ko.observableArray();
        self.newdata = ko.observable();
        self.currentPage = ko.computed(function () {
            var pagesize = parseInt(self.pageSize(), 10),
            startIndex = pagesize * self.currentPageIndex(),
            endIndex = startIndex + pagesize;
            return self.salesdata.slice(startIndex, endIndex);
        });
        self.nextPage = function () {
            if (((self.currentPageIndex() + 1) * self.pageSize()) < self.salesdata().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.salesdata().length / self.pageSize())) - 1);
            }
        }
        //Here I'm trying to update ViewModel
        self.request = function (uri) {
            $.ajax({
                url: uri,
                contentType: 'application/json',
                data: [],
                type: 'GET',
                cache: false,
            success: function (data) {
                ko.mapping.fromJS(data.$values, {}, self.salesdata);
            }
            });
        }
    }
    $(document).ready(function () {
        $.ajax({
            url: "/api/sales",
            type: "GET",
            cache: false,
        }).done(function (data) {
            var vm = new viewModel();
            vm.salesdata(data.$values);
            ko.applyBindings(vm);
        }).error(function (xhr, status, error) {
            var err = eval("(" + xhr.responseText + ")");
            alert(err.Message);
        });
        //Here i'm calling for ViewModel update
        $(".btn-default").click(function () {
            days = $(this).val();
            var uri = "/api/sales?days=" + days;     
            new viewModel().request(uri);
        });
    });
</script>
Run Code Online (Sandbox Code Playgroud)

UPDATE. 我查了一段代码,我得到的新数据如下:

self.request = function (uri) {
                $.getJSON(uri, function (data) {
                    ko.mapping.fromJS(data.$values, {}, viewModel);
                });
            }
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不起作用.这里没有任何JS错误,控制器返回更新数据的适当部分.

bra*_*r24 6

我是所有这一切的新手,但是如果我正确地阅读你的代码,你就是在视图模型的新实例上调用请求函数而不是绑定到html文档的实例.您需要在初始get调用完成后创建的视图模型上进行请求调用.

更新:对不起,我应该更具体地说明我所指的代码.在代码块的末尾,您有以下代码:

    $(".btn-default").click(function () {
        days = $(this).val();
        var uri = "/api/sales?days=" + days;     
        new viewModel().request(uri);
    });
Run Code Online (Sandbox Code Playgroud)

在此代码中,似乎每次单击默认按钮时,都会创建一个新的视图模型,并在该视图模型上调用请求函数.

在文档就绪功能中,您要定义加载销售数据后发生的事情,您可以使用以下代码创建html文档实际绑定到的视图模型:

    var vm = new viewModel();
    vm.salesdata(data.$values);
    ko.applyBindings(vm);
Run Code Online (Sandbox Code Playgroud)

什么都没有在这个视图模型上调用请求函数.我想知道你真正想要的是以某种方式将此视图模型中的请求函数绑定到默认按钮.


GôT*_*ôTô 5

我会尝试salesdata通过提供context: self和使用以下success方法来更新viewmodel observable :

self.request = function (uri) {
        $.ajax({
            url: uri,
            contentType: 'application/json',
            context: self,
            data: [],
            type: 'GET',
            cache: false,
        success: function (data) {
            this.salesdata(data.$values);
        }
        });
    }
Run Code Online (Sandbox Code Playgroud)

编辑:

我可以看到你用jQuery附加了一个click事件.您应该使用knockout clck绑定:

<button data-bind="click: clickEvent" value="1">Click me!</button>
Run Code Online (Sandbox Code Playgroud)

并在viewmodel中

clickEvent: function (data, event) { 
    days = event.target.value;
    var uri = "/api/sales?days=" + days;     
    data.request(uri);
}
Run Code Online (Sandbox Code Playgroud)

这样您就可以检索视图模型,而不是像创建新模型一样创建新视图模型 new viewModel().request(uri);

有关点击绑定的更多信息,请访问http://knockoutjs.com/documentation/click-binding.html