我正在使用KnockoutJS ......
我的viewModel中有observableArray
部电影。当用户按标题搜索电影时,数组会更新,因此推送到数组中的典型json响应将如下所示...
{data : [{
Id: 12345,
Title: 'Movie1',
Year: 2010,
Character: [{
Name: 'Character1',
Person: { Id: 1, Name: 'Person1' }
},{
Name: 'Character2',
Person: { Id: 2, Name: 'Person2' }
}],
UserMovies: [{
Id: 8
IsWatched: false,
Rating: 3.5,
UserId: 'e1e9c075-1ded-4e7d-8d30-d5d1fbd47103'
}]
}]}
每部电影的UserMovies
属性代表特定于该用户的信息,例如他们的个人评级或他们是否已观看过电影等。
我为用户提供了将电影“添加”到数据库中的集合的功能。当他们将电影添加到他们的集合时,会发回一个json响应,该响应具有该电影的更新UserMovies
属性。
我正在尝试更新该属性,然后将其保留到淘汰模板中。这是我当前的viewModel ......
function viewModel() {
// private properties
var self = this;
// public properties
self.movies = ko.observableArray([]);
self.searchValue = ko.observable();
// public operations
self.search = function () {
self.isLoading(true);
$.getJSON(arguments[0].action, { name: this.searchValue() }, function (data) {
self.movies(data);
});
};
self.add = function (movie) {
$.ajax({
type: 'POST',
url: arguments[1].currentTarget.attributes[1].value,
data: JSON.stringify({ movie: movie }),
contentType: 'application/json',
dataType: 'json',
success: function (data) {
// how to just update UserMovies property and persist to template for the given movie?
}
});
};
}
ko.applyBindings(new viewModel());
我不知道如何更新属性,但是为了将数据持久保存到淘汰模板我认为这是因为每部电影的UserMovies
属性本身不是可观察的,所以如果它没有更新,那么自动更改模板。
我一直在阅读有关映射插件的内容,它会使每个属性都成为可观察的。这可能会解决我的持久性问题,但我仍然不确定如何更新UserMovies
属性,无论它是observableArray
还是通过映射插件。
更新
我使用映射插件创建了一个小提琴。如果我返回整部电影而不仅仅是UserMovies
属性,那么更新数组中的项目会更容易。我有一些问题让它工作,我正在努力弄清楚如何为UserMovies
属性创建'key'的映射。 http://jsfiddle.net/cmBd9/3/
答案 0 :(得分:0)
正如您自己正确指出的那样,UserMovies属性不是可观察的这一事实意味着即使您更新它,UI也不会发生任何事情。尽管如此,这里是你如何更新(不可观察的)UserMovies:
self.add = function (movie) {
$.ajax({
type: 'POST',
url: arguments[1].currentTarget.attributes[1].value,
data: JSON.stringify({ movie: movie }),
contentType: 'application/json',
dataType: 'json',
success: function (data) {
ko.utils.arrayForEach(self.movies(), function(m) {
if (m.Id == movie.Id) {
m.UserMovies = data;
}
});
}
});
};
绝对查看mapping plugin。我唯一关心的是文档显示了如何从JSON初始映射对象,以及稍后如何从JSON更新整个对象。
但是,它似乎没有提到任何关于从JSON映射对象以及稍后出现并仅从JSON更新该对象的部分的内容,因此我不确定这是否有效或不。
如果您遇到问题,可以尝试让add方法的服务调用返回整个影片对象,以便您更加密切地关注映射插件所支持的模型。
答案 1 :(得分:0)
我能够使用映射选项使用映射插件。我将UserMovies
的密钥设置为每个UserMovie
的ID,因此当调用fromJS()
时,它会查看每个UserMovie
的ID以告知是否更新或添加一个新的UserMovie
这是我更新的代码......
function viewModel() {
// private properties
var self = this;
var mapping = {
'UserMovies': {
key: function (data) {
return ko.utils.unwrapObservable(data.Id);
}
}
};
// public properties
self.movies = ko.mapping.fromJS([]);
self.searchValue = ko.observable();
// public operations
self.search = function () {
self.isLoading(true);
$.getJSON(arguments[0].action, { name: this.searchValue() }, function (data) {
ko.mapping.fromJS(data, {}, self.movies);
});
};
self.add = function (movie) {
$.ajax({
type: 'POST',
url: arguments[1].currentTarget.attributes[1].value,
data: ko.toJSON({ movie: movie }),
contentType: 'application/json',
dataType: 'json',
success: function (data) {
if(data.success) {
ko.mapping.fromJS(data.movie, mapping, movie);
}
}
});
};
}