请参考这个问题,因为它有助于解决我的问题的50%:
另外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);
});
}
答案 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.fromJS
或ko.mapping.fromJSON
。
fromJS
和fromJSON
的参数将依次为:
data
)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>