Updating Knokout.js ViewModel at the click of a button

Well, this is not the best description of the situation ... Anyway, I'm trying to update my ViewModel, but it does not work. By default, I get data from the controller function and by clicking a button - from another function in the same controller, but the ViewModel contains only the data received after the first initialization of the 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>

UPDATE I ran a block of code where I get new data as follows:

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

Unfortunately this does not work. There are no JS errors here, the controller returns the correct part of the updated data.

+4
source share
4 answers

. , @GoTo: viewmodel .

<button type="button" class="btn btn-default" id="7" value="7" data-bind="click: getDays.bind($data, '7')">7</button>

. , self.salesdata viewModel. , - , - <td data-bind="text: moment($data.whensold).format('DD.MM', 'ru')"></td>.

 self.getDays = function (days) {
                    var uri = "/api/sales?days=" + days;
                    $.getJSON(uri, function (data) {
                        ko.mapping.fromJS(data.$values, {}, self.salesdata);
                    });
                }
0

, , , , html-. , .

: , , . :

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

, , , .

, , , , , html:

    var vm = new viewModel();
    vm.salesdata(data.$values);
    ko.applyBindings(vm);

. , , , .

+6

viewmodel salesdata observable, context: self success:

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

EDIT:

, click jQuery. clock :

<button data-bind="click: clickEvent" value="1">Click me!</button>

viewmodel

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

, new viewModel().request(uri);

. http://knockoutjs.com/documentation/click-binding.html

+5

@brader24 :

click :

new viewModel().request(uri);

- viewModel ( , , ), request. viewModel (, , DOM!). , , , , , viewModel , .

( viewModel ).

$(document).ready(function () {
    var vm = new viewModel(); // declare (and instantiate) your view model variable outside the context of the $.ajax call so that we have access to it in the click binding
    $.ajax({
        url: "/api/sales",
        type: "GET",
        cache: false,
    }).done(function (data) {
        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;     
        vm.request(uri); // don't use a new instance of a view model - use the one you have already instantiated
    });
});

Using click binding for knockout instead of binding a click event handler using jQuery is usually the recommended route, but not required - so your existing code (with the changes above) should work fine. For more information about this, see Using Unobtrusive Event Handlers in Knockout Docs.

+3
source

Source: https://habr.com/ru/post/1538065/


All Articles