淘汰赛仅更新部分视图模型

Posted

技术标签:

【中文标题】淘汰赛仅更新部分视图模型【英文标题】:Knockout update only part of the viewmodel 【发布时间】:2019-11-14 02:18:24 【问题描述】:

让我们假设来自 JS 的视图模式

var js =  
            Foo1 : 
                BarA : 'text',
                BarB : 'other text' ,
            Foo2 : 
                BarC : 'some text' ; 

 var vm = ko.mapping.fromJS(js);
  ko.applyBindings(vm);

现在我可以了

vm.Foo1.BarB('hello world');

我也可以做类似的事情

var js =  
            Foo1 : 
                BarA : 'text',
                BarB : 'hello world' ,
            Foo2 : 
                BarC : 'some text' ; 

 ko.mapping.fromJS(js, vm);

这两种情况都会更新绑定到 vm.Foo1.BarB 的任何字段

我想做的事情是这样的

var foo = 
               BarA : 'text',
               BarB : 'hello world' ; 

     ko.mapping.fromJS(foo, vm.Foo1);

这个不行,我也试过

vm.Foo1(ko.mapping.fromJS(foo));
//and
vm.Foo1 = ko.mapping.fromJS(foo);

它们都不起作用。

我需要这个,因为在我的真实场景中,我的模型是从 web 服务返回的,更新 Foo1 和 Foo2 也会返回,我不想要太多的自定义映射。

【问题讨论】:

【参考方案1】:

显然还有一些神秘的附加参数..

ko.mapping.fromJS(foo, , vm.Foo1);

我不知道第二个参数的作用,但如果你使用它,它就可以了。

https://***.com/a/29598785/2968001

【讨论】:

这个fromJS签名被描述为in the docs。【参考方案2】:

据我所知,这是不可能的。但你可以这样做:

var js =  
            Foo1 : 
                BarA : 'text',
                BarB : 'other text' ,
            Foo2 : 
                BarC : 'some text' ; 

var vm = ko.mapping.fromJS(js);
ko.applyBindings(vm);

//later, after fetching data from the webservice:
//data = 
//   Foo1 : 
//      BarA : 'text',
//      BarB : 'other text' ,
//; note: Foo2 is not defined

ko.mapping.fromJS(data, , vm);

映射后,只会更新 Foo1(及其子项)。

【讨论】:

【参考方案3】:

您不想进行自定义映射,但考虑到可能需要更改 rest api,如果您直接依赖 API 结果,请考虑这意味着什么。

即假设你有一个 api 结果:


   name: 'Ryan',
   title: 'Developer'
   gender: 'M',
   birthDate: '01-01-1984',
   employeeCode: '0123156'

所以你在你的标记中使用了一堆东西,比如:

<label data-bind="text: user.employeeCode"></label>

在 100 多个地方的标记中,您的字段名称都被写入了。您在计算的可观察对象、函数等中依赖它们。您对该 API 有 100% 的硬依赖。

如果要更改或替换该 api,并为返回的数据使用不同的格式,您的整个应用程序将中断,您必须修复很多东西。

另一方面,如果您有一个为 api 结果创建自定义对象实例的服务层 js 文件,那么您只需更改您的服务层。

您可以轻松切换 api,而无需更改任何可观察对象、ui 绑定等。您已经在应用程序和它的后端数据之间创建了一个耦合层,您可以交换耦合以更改整个后端。

我知道这不是您问题的答案,但我会重新考虑您是 api 结果映射策略或将其考虑在内。

【讨论】:

以上是关于淘汰赛仅更新部分视图模型的主要内容,如果未能解决你的问题,请参考以下文章

添加项目以淘汰视图模型,不更新视图

我可以以编程方式触发淘汰视图模型更新吗?

添加项目以淘汰视图模型,不会更新视图

ajax发布后淘汰js更新视图模型

当页面通过ajax作为部分加载时,如何重新绑定淘汰视图模型?

在淘汰视图模型声明中调用 jquery 函数。 (主要是语法问题)