Knockout JS - 使用AJAX Call更新viewModel

时间:2014-07-31 10:49:44

标签: ajax mvvm knockout.js viewmodel

有一些类似的问题,但没有帮助我解决我的问题。用AJAX更新viewModel后,我无法在页面/视图上更新我的结果。如果我重新加载页面,我将获得有效的AJAX响应更新视图,但是当我单击btnAdvancedSearch

我有简单的HTML:

    <div>
        <input type="button" id="btnAdvancedSearch" data-bind="click: refresh" />
    </div>

    <div id="resultslist1" data-bind="template: { name: 'rest-template', foreach: restaurants }">
    </div>

我绑定文档加载:

$(document).ready(function () {
     ko.applyBindings(new RestaurantsListViewModel());
});

我的viewModel是这样的,在其中我调用了与按钮绑定的刷新

// Overall viewmodel for this screen, along with initial state
function RestaurantsListViewModel() {
    var self = this;
    self.restaurants = ko.observableArray([]);

    var mappedRests = $.map($.parseJSON(sessionStorage.getItem('searchResults')), function (item) { return new Restaurant(item) });
    self.restaurants = mappedRests;

    self.refresh = function () {
    updateRestaurantsList(); //Method executes AJAX and saves result to session.
    var mappedRests2 = $.map($.parseJSON(sessionStorage.getItem('searchResults')), function (item) { return new Restaurant(item) });
    self.restaurants= mappedRests2;
}

}

我在这里缺少什么?

由于

2 个答案:

答案 0 :(得分:1)

我试过等待AJAX​​这样完成:

 // Overall viewmodel for this screen, along with initial state
 function RestaurantsListViewModel() {
     var self = this;
     self.restaurants = ko.observableArray([]);

     var mappedRests = $.map($.parseJSON(sessionStorage.getItem('searchResults')),     function (item) { return new Restaurant(item) });
      self.restaurants = mappedRests;

      self.refresh = function () {

    var latitude = sessionStorage.getItem('latitude');
    var longitude = sessionStorage.getItem('longitude');
    var query = '{"Accepts_Reservations":"' + $('#chkReservation').is(":checked") + '","Accepts_Cards":' + $('#chkAcceptsCards').is(":checked") + '"}';
    var searchResults = getRestaurantsAdvancedSearchAJAX(query, latitude, longitude, 40);

    searchResults.success(function (data) {
        var information = data.d;

        var mappedRests2 = $.map($.parseJSON(information), function (item) { return new Restaurant(item) });

        self.restaurants = mappedRests2;
    });

  };
};

编辑1

一旦你宣布了你的观察者:

self.restaurants = ko.observableArray([]);

如果您想要更新restaurants,则无法执行此操作:

self.restaurants = mappedRests2;

相反,你需要这样做:

self.restaurants(mappedRests2);

答案 1 :(得分:0)

updateRestaurantsList(); //Method executes AJAX and saves result to session.

上面一行后面的注释表明此方法正在进行异步调用。因此,很可能在填充sessionStorage之前执行该行。也许考虑让updateRestaurantsList回复承诺。然后你可以将你的代码更新为:

updateRestaurantsList().then(function() {
    var mappedRests2 = $.map($.parseJSON(sessionStorage.getItem('searchResults')), function (item) { return new Restaurant(item) });
    self.restaurants= mappedRests2;
});

这样,填充mappedRests2变量的调用就不会在updateRestaurantsList方法完成之后发生。

编辑1

请务必不要使用等号将值赋给observable。

// Overall viewmodel for this screen, along with initial state
 function RestaurantsListViewModel() {
     var self = this;
     self.restaurants = ko.observableArray([]);

     var mappedRests = $.map($.parseJSON(sessionStorage.getItem('searchResults')),     function (item) { return new Restaurant(item) });
      self.restaurants(mappedRests);

      self.refresh = function () {

    var latitude = sessionStorage.getItem('latitude');
    var longitude = sessionStorage.getItem('longitude');
    var query = '{"Accepts_Reservations":"' + $('#chkReservation').is(":checked") + '","Accepts_Cards":' + $('#chkAcceptsCards').is(":checked") + '"}';
    var searchResults = getRestaurantsAdvancedSearchAJAX(query, latitude, longitude, 40);

    searchResults.success(function (data) {
        var information = data.d;

        var mappedRests2 = $.map($.parseJSON(information), function (item) { return new Restaurant(item) });

        self.restaurants(mappedRests2);
    });

  };
};