简体   繁体   English

如何使用映射插件刷新Knockout ViewModel

[英]How to Refresh Knockout ViewModel Using Mapping Plugin

I have the following Knockout ViewModel: 我有以下Knockout ViewModel:

var EditorViewModel = function () {

    var self = this;

    self.addData = function (_data) {
        ko.mapping.fromJS(_data, {}, self);
    };
};

which is used as such: 可以这样使用:

var viewModel = new EditorViewModel();
viewModel.addData(model);
ko.applyBindings(viewModel);

For info, the data for viewModel.addData() comes from an AJAX call. 有关信息, viewModel.addData()的数据来自AJAX调用。

The View/ViewModel is populated with no problem the first time round when ko.applyBindings is called. 第一次调用ko.applyBindings时,View / ViewModel不会出现任何问题。 However, if I later pull new data from the server via AJAX and then call either: 但是,如果以后我通过AJAX从服务器提取新数据,然后调用以下任一方法:

viewModel.addData(someNewAjaxData)

or 要么

ko.mapping.fromJS(someNewAjaxData, {}, viewModel);

Then Knockout does not update the view with the new data. 然后,淘汰赛不会使用新数据更新视图。 Hopefully this is a trivial problem...?! 希望这是一个小问题...?!

KnockoutJS Mapping has the ability to specify a key for an item. KnockoutJS映射可以为项目指定键。 This lets KnockoutJS know when an item needs to be created versus updated. 这使KnockoutJS知道何时需要创建或更新项目。

 var ItemViewModel = function(d){ var self = this; self.id = ko.observable(d.id); self.text = ko.observable(d.text); // We assign it when the object's created to demonstrate the difference between an // update and a create. self.lastUpdated = ko.observable(new Date().toUTCString()); } var EditorViewModel = function(){ var self = this; self.items = ko.observableArray(); self.addData = function(d){ ko.mapping.fromJS(d, { 'items': { 'create': function(o){ return new ItemViewModel(o.data); }, 'key': function(i){ return ko.utils.unwrapObservable(i.id); } } }, self); console.info(self); } self.addMoreData = function(){ self.addData({ 'items': [ {id:1,text:'Foo'}, {id:3,text:'Bar'} ] }); } } var viewModel = new EditorViewModel(); viewModel.addData({ items:[ {id:1,text:'Hello'}, {id:2,text:'World'} ] }); ko.applyBindings(viewModel); 
 <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">Hello, world!</h3> </div> <ul class="list-group"> <!-- ko foreach:items --> <li class="list-group-item"> <span class="text-muted" data-bind="text:id"></span> <span data-bind="text:text"></span> <span class="text-danger pull-right" data-bind="text:lastUpdated"></span> </li> <!-- /ko --> <li class="list-group-item" data-bind="visible:!items().length"> <span class="text-muted">No items.</span> </li> </ul> <div class="panel-footer"> <a href="#" data-bind="click:addMoreData">Update</a> </div> </div> </div> </div> </div> 

Observe, in the attached snippet, how the first item's lastUpdated value is assigned when it's created, but is left unchanged when it's updated. 在随附的代码段中,观察创建第一项的lastUpdated值是如何分配的,但是在更新时将其保持不变。 This is because the mapper sees the ID already exists in items and simply updated the properties. 这是因为映射器看到ID已存在于items并且只是更新了属性。 But, for item with the id 3, a new model is created. 但是,对于ID为3的商品,将创建一个新模型。

All knockout bibdings were subscribed to the first created model. 所有剔除出价都订阅了第一个创建的模型。 You recreate the bound model on every ajax response. 您可以在每个ajax响应上重新创建绑定模型。 Your problem seems similar that was discussed in this stackoverflow article . 您的问题似乎与本stackoverflow文章中讨论的问题相似。 The same osbervable should be bound to the markup. 相同的osbervable应该绑定到标记。

Try this (may be you should support an empty model binding): 试试这个(也许你应该支持一个空的模型绑定):

// in the start of app
var observableModel = ko.observable();
ko.applyBindings(observableModel);

// on every ajax call
var viewModel = new EditorViewModel();
viewModel.addData(model);
observableModel(viewModel);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将RequireJS与Knockout和Knockout映射合并插件一起使用 - Using RequireJS with Knockout and Knockout Mapping Merge Plugin 推迟或暂停评估挖空中的依赖项,直到完全更新viewmodel(例如使用映射插件) - Defer or pause evaluating dependencies in knockout until viewmodel is completely updated (using for instance the mapping plugin) 我是否过度使用Knockout映射插件总是用它来做我的viewmodel? - Am I overusing the Knockout mapping plugin by always using it to do my viewmodel? Knockout映射插件检索到的viewModel对象与更新的对象之间的不一致 - Inconsistency between Knockout mapping plugin retrieved viewModel objects and newed ones 在ViewModel构造函数中使用Knockoutjs映射插件 - Using Knockoutjs Mapping Plugin inside viewmodel constructor 如何使用由基因敲除(viewout)插件创建的视图模型绑定到输入元素 - How to bind to an input element using a view model created by the knockout.viewmodel plugin 使用映射插件将JSON对象映射到敲除数组 - Mapping a JSON object to a knockout array using mapping plugin 使用Knockout映射插件正确映射数组元素 - Correctly mapping array element using the Knockout mapping plugin 如何使用模板中的Knockout映射插件映射到来自服务器对象的数组? - How to map to an Array coming from server object using Knockout Mapping plugin in templates? 如何使用Knockout映射插件映射到来自服务器对象的数组并进行一些计算? - How to map to an Array coming from server object using Knockout Mapping plugin and have some computed?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM