6

我试图弄清楚我对 Knockout 的映射库有什么误解。我已将其简化为一个简单的示例,并且仍然可以通过fromJS调用使其失败(而不是使用映射变量进行更新)。

在这个例子中我有什么根本错误?

// Here's my view model
var ViewModel = function() {
    this.firstName = ko.observable('first');
    this.lastName = ko.observable('last');
};

var myVM = new ViewModel();

ko.applyBindings(myVM); // Apply to Knockout (works)

myVM.lastName('maiden name'); // Test an update (works)

var newData = {firstName: 'new', lastName: 'person'};

// Try update the ViewModel
ko.mapping.fromJS(newData, myVM); //(No update, or error)

// Intended result - UI updates to 'new person'

以及相应的视图:

<div class='liveExample' >   
    <p>First name: <input data-bind='value: firstName' /></p> 
    <p>Last name: <input data-bind='value: lastName' /></p> 
</div>

我的JS 小提琴示例

4

2 回答 2

11

ko.mapping.fromJS处理参数有点棘手(请参阅我的答案here),因此第二个参数通常是映射选项:

ko.mapping.fromJS(newData, {} /* mapping options */, myVM); 

演示JSFiddle

于 2013-09-12T06:36:18.627 回答
7

我发现如何只使用 2 个数据参数。

创建您的 ViewModel 作为原始数据的映射,然后使用ko.mapping.fromJS(data, ViewModel).

更新的jsFiddle

解释

Knockout 使用一个名为的属性mappingProperty = "__ko_mapping__"来识别数据之前映射的时间。如果找到,它会将第二个参数设置为目标(本例中为 ViewModel)。

ko.mapping.js调试版本的摘录:

var mappingProperty = "__ko_mapping__";

[...]

if (arguments.length == 2) {
  if (arguments[1][mappingProperty]) {
    target = arguments[1];
  } else {
    options = arguments[1];
  }
} 
于 2013-09-12T08:23:51.450 回答