我遇到了ko.mapping的问题 1)在客户端ViewModel上:
var data = [ {id : 1, title: "C"} ]
2)从服务器(对象数组):
[ {id : 1, title: "C"},{number : 2, title: "B" } ]
3)我只有在存在时才需要替换数据:
[ {id : 1, title: "C"} ] => data replace self.books
3)我尝试使用ko.mapping插件,但结果为var mappingOptions = {
key: function (data) {
return ko.utils.unwrapObservable(data.id);
}
};
ko.mapping.fromJS(data, mappingOptions, self.books);
awk -F '=| ' '/^ts=/{printf $2","} /de ad be ef/{if(!a){printf $15$16;a=1}else{print $1$2;a=0}}' data.log
THX:)
答案 0 :(得分:1)
你可以(可能)使用ko.mapping插件,但我认为如果你试图在普通的javascript中解决这个问题,它会让你受益。代码不多,至少你会更好地理解插件在幕后做的事情。
您的books
数组需要与更新数组(data
)合并。您使用id
属性来检查是否相等。因此,简而言之,您必须:
books
数组,以便淘汰赛可以找出已更改的内容直接实现更新功能:
var books = ko.observableArray([
{id : 1, title: "A"},
{id : 2, title: "B" }
]);
var updateBooks = function(updates) {
var oldBooks = books();
var newBooks = oldBooks.map(function(book) {
var update = updates.find(function(update) {
return update.id === book.id;
});
return update || book;
});
books(newBooks);
};
ko.applyBindings({
books: books,
updateBooks: updateBooks
});
updateBooks([{ id: 1, title: "C" }]);

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: books">
<li>
<span data-bind="text:id"></span>
<strong data-bind="text: title"></strong>
</ul>
&#13;
如果您不介意性能要求,并且您可以确定更新中的所有id
已在oldBooks
中提供(即更新),则此实施将有效不包含新书籍。它还创建了一个包含新旧书对象组合的新数组。这使得淘汰赛更难以有效地呈现列表。
通过更多工作,您可以制作具有可观察title
属性的书籍视图模型。通过使用基于id
的地图,您可以加快更新周期。
var Book = function(options) {
this.id = options.id;
this.title = ko.observable(options.title);
// Instead of creating new Books all the time,
// we update its observable property so only the changed values
// are re-rendered
this.update = function(options) {
this.title(options.title);
}.bind(this);
};
Book.create = function(options) { return new Book(options); };
var BookList = function(bookData) {
this.books = ko.observableArray(bookData.map(Book.create));
// Compute an object that stores each book by id.
// Whenever the books array changes, this object is updated.
// Access a book by calling: this.bookMap()[bookId]
this.bookMap = ko.pureComputed(function() {
return this.books().reduce(function(map, book) {
map[book.id] = book;
return map;
}, {});
}, this);
};
BookList.prototype.updateBooks = function(updates) {
// Apply each update
updates.forEach(function(newBook) {
// Find the book by id in our map
var bookRef = this.bookMap()[newBook.id];
if (bookRef) {
// The book has its own viewmodel, with an update method
bookRef.update(newBook);
}
}.bind(this));
};
var data = [
{id : 1, title: "A"},
{id : 2, title: "B" }
];
var vm = new BookList(data);
ko.applyBindings(vm);
vm.updateBooks([{ id: 1, title: "C" }]);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: books">
<li>
<span data-bind="text:id"></span>
<strong data-bind="text: title"></strong>
</ul>
&#13;