来自json模型的Knockout JS更新视图

时间:2015-08-08 17:58:11

标签: javascript json knockout.js

请参考这个问题,因为它有助于解决我的问题的50%:

Knockout Mapping reading JSON

另外50%的问题是更新视图,如果您两次调用ko.applyBindings(viewModel);,则会出现错误未捕获错误:您无法多次将绑定应用于同一元素。

即使在他们提到的官方淘汰网站上,也没有人在网上提出解决方案:

// Every time data is received from the server:
ko.mapping.fromJS(data, viewModel);

也不起作用。任何人都知道每次获取新数据时更新我的​​视图的正确方法是什么,知道该视图已经通过ko.applyBindings(viewModel);进行了初始化?

修改

HTML:

<select class="input-short artist-list" data-bind="foreach: model">
   <option value="1" selected="selected" data-bind="text: name"></option>                                           
 </select>  

JS

var viewModel = {
        model: ko.observableArray()            
    };


$(window).load(function(){
    fetchArtists();  

  })
function fetchArtists() //this function fetches all artists
{
     // load data
       $.post( "../db/fetch/", { table: "artists"})
          .done(function( data ) {
          //  artists=JSON.parse(data);
          data=JSON.parse(data);//data is array of objects e.g [{name:"xxx"},{name:"yyy"}]   
          artists.model = ko.mapping.fromJS(data);         
          ko.applyBindings(artists);      
          });

}

2 个答案:

答案 0 :(得分:2)

这应该做你想做的事:

<强> JS

var viewModel = {
    model: ko.observableArray()            
};

$(window).load(function(){
    ko.applyBindings( viewModel );
    fetchArtists();  
})

function fetchArtists()
{
     $.post( "../db/fetch/", { table: "artists" } ).done(function( data ) {
          ko.mapping.fromJSON( data, {}, viewModel.model ); 
     });

}

正如@SVSchmidt所提到的,每个元素只能调用一次ko.applyBindings()。所以你会ko.applyBindings一次(在页面加载/准备就绪),然后直接更新observableArray(模型)或使用映射插件。

直接更新observableArray(模型)意味着值将是普通值。但如果您希望这些值是可观察的,那么ko.mapping将是合适的。

因此,要使用映射插件,如果您有原始JSON数据,则可以调用ko.mapping.fromJSko.mapping.fromJSON

fromJSfromJSON的参数将依次为:

  • 要映射的传入数据(在您的情况下为data
  • 可用于控制映射的选项对象(目前为空对象)
  • 您要更新的目标viewmodel或viewmodel属性(在您的情况下为viewModel.model

以下是一个工作演示,向您展示了其运作方式:http://plnkr.co/edit/4g1izaLYraBjganjX2Ue?p=preview

答案 1 :(得分:1)

在knockout中,ViewModel一次应用于视图(applyBindings)。每次更新与data-bind绑定的observable都会更新(例如,为它们分配新数据),视图将被重新呈现。你的错误是绑定一个不可观察的(模型)并重新定义每个函数调用的artists.model。

您应该按照以下方式进行:

var viewModel = {
    artists: ko.observableArray()          
};


$(window).load(function(){
    fetchArtists();  
});

function fetchArtists()
{
     // load data
       $.post( "../db/fetch/", { table: "artists"})
          .done(function( data ) {
              viewModel.artists(JSON.parse(data)); // assign new values to artists observable          
       });
}

<强> HTML

<select class="input-short artist-list" data-bind="foreach: artists">
   <option value="1" selected="selected" data-bind="text: name"></option>                                           
</select>

<script>
    ko.applyBindings(viewModel); // apply ViewModel
</script>