如何在Knockout.js中一次性批量更新对象所有属性值
结论
你期望的直接调用self.person(temp)完成批量赋值的写法不可行:self.person是存储了多个ko.observable实例的普通JavaScript对象,本身不是可调用的 observable 类型,直接执行会抛出函数调用错误。
另外你最初的逐个赋值示例存在笔误:self.name.id("AAAA")写法错误,正确写法应为self.person.name("AAAA")。
可行的批量赋值实现方案
方案1:使用 Knockout 官方 mapping 映射插件(最简便)
这是 Knockout 生态里处理普通对象与观察对象转换、批量更新的标准方案,不需要手动逐属性赋值。
引入插件后,如果你已经提前定义好了self.person下的各个 observable 属性,只需要一行代码即可完成批量更新:
self.person = { id: ko.observable(), name: ko.observable() }; const temp = { id: "1", name: "AAAA" }; // 批量更新:第三个参数为待更新的目标观察对象集合 ko.mapping.fromJS(temp, {}, self.person);
如果是初始化阶段,还可以直接通过普通对象生成完整的带 observable 属性的person对象,后续更新时也不需要再传空配置项:
// 初始化直接生成观察对象 const initData = {id: "", name: ""}; self.person = ko.mapping.fromJS(initData); // 后续更新 const newData = {id: "1", name: "AAAA"}; ko.mapping.fromJS(newData, self.person);
方案2:无插件实现通用批量更新方法
如果不想额外引入插件,可以自己写一个简单的遍历更新方法,逻辑为遍历传入普通对象的键名,判断目标对象下的同名属性是否为 observable,是则传入新值完成更新:
// 通用批量更新工具方法 function setObservableValues(target, source) { Object.keys(source).forEach(key => { if (ko.isObservable(target[key])) { target[key](source[key]); } }); } // 使用示例 self.person = { id: ko.observable(), name: ko.observable() }; const temp = { id: "1", name: "AAAA" }; setObservableValues(self.person, temp);
方案3:将person本身定义为observable(不推荐)
如果要强行实现self.person(temp)的调用形式,需要把self.person本身定义为一个 observable,但这种方案存在明显缺陷:任意属性变化都会触发整个person对象的订阅回调,无法细粒度监听单个属性变更,除非配合深度映射逻辑,否则灵活性和性能表现都较差,常规业务场景不推荐使用。
// 定义方式 self.person = ko.observable({ id: "", name: "" }); const temp = { id: "1", name: "AAAA" }; // 可以直接调用赋值,但会整体替换内部对象 self.person(temp);
内容的提问来源于stack exchange,提问作者MOz
相关产品推荐
相关产品推荐

