【发布时间】:2017-10-17 02:19:31
【问题描述】:
两者有什么区别?
当然它们是同一个东西,因为一个展开的 observable 剥离为一个 js 原语。那么为什么要使用 ko.toJS,反之亦然呢?
另外,为什么会有 ko.mapping.toJS?这与 ko.toJS 不一样吗? 在 knockoutJS 中似乎有几个函数可以做同样的事情,但它们存在一定是有原因的。
【问题讨论】:
标签: knockout.js
两者有什么区别?
当然它们是同一个东西,因为一个展开的 observable 剥离为一个 js 原语。那么为什么要使用 ko.toJS,反之亦然呢?
另外,为什么会有 ko.mapping.toJS?这与 ko.toJS 不一样吗? 在 knockoutJS 中似乎有几个函数可以做同样的事情,但它们存在一定是有原因的。
【问题讨论】:
标签: knockout.js
它们之间存在差异。
ko.toJS 获取一个对象并“打开”并从所有可观察对象中清除该对象。它对整个对象图执行此操作。我的行为很像一个序列化程序,这意味着如果你有循环引用,你就会遇到问题。它在内部使用mapJsObjectGraph,这太复杂了,我现在无法在脑海中完全编译。但是,当我需要将内容发回服务器时,我倾向于使用它。
ko.utils.unwrapObservable 只是确定该值是否是可观察的,如果是,则返回基础值。如果不是,它只返回值。如果您使用映射插件,这可能会很方便,例如,您最终可能会得到可以同时具有可观察对象和不可观察对象的模型。
ko.mapping.toJS 是列表中唯一一个在功能方面可能被怀疑有些重复的产品。它用于将映射的对象图映射回其原始状态。它看起来比 ko.toJS 简单得多,但我还没有使用它(还)所以老实说我不能告诉你更多关于它的信息。阅读更多关于它的信息here。
【讨论】:
myObservable() 这样的括号来获得基础价值。但如果它不是一个 observable 就会失败。
ko.utils.unwrapObservable 将返回仍然包含 observable 实例完整的内部对象,而ko.toJS 也将打开它,返回一个带有普通值的普通对象。这就是 MikaelÖstberg 的回答中的“它为整个对象图执行此操作”的意思,我认为这非常重要。
关于ko.mapping.toJS(...) 与ko.toJS(...)
这将创建一个仅包含以下属性的未映射对象 作为原始 JS 对象一部分的映射对象。所以在 换句话说,您手动添加到的任何属性或函数 您的视图模型被忽略。默认情况下,唯一的例外是 rule 是 _destroy 属性,它也将被映射回来,因为 它是您销毁物品时 Knockout 可能生成的属性 来自 ko.observableArray。有关更多信息,请参阅“高级用法”部分 有关如何配置的详细信息。
因此,这意味着映射插件只会将 IT 为您创建的内容转换回来。如果您合并了一个视图模型或添加了计算甚至只是常规的可观察对象,它们将不会返回到模型中。
如果您有一个混合视图模型(部分映射和部分手动创建),您最好创建 JSON 以以混合方式发送回服务器。
你可以把它放在你的页面上,看看这两个模型有什么不同:
<h2>ko.TOJSON()</h2>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
<h2>ko.mapping.toJS</h2>
<pre data-bind="text: JSON.stringify(ko.mapping.toJS($root), null, ' ')"></pre>
(我不确定如何“美化”来自ko.mapping.toJSON 的响应,所以我只使用了 JSON.stringify
【讨论】:
这就是 ko.mapping.toJS & ko.toJS:
var viewModelRaw = { prop: 0 };
var viewModel = ko.mapping.fromJS(viewModelRaw);
var _raw = ko.mapping.toJS(viewModel); // = { prop: 0 }
var _rawWithTraces = ko.toJS(viewModel); // = { prop: 0, __ko_mapping__: .... }
如您所见,ko.mapping.toJS() 返回一个反映视图模型的干净 JS 对象,
不留下任何剔除属性,而 ko.toJS() 留下一些剔除属性..
我不知道他们为什么那样做......
【讨论】: