【问题标题】:KnockoutJS: Stop a particular property from setting dirty flagKnockoutJS:阻止特定属性设置脏标志
【发布时间】:2013-11-13 19:28:42
【问题描述】:

在 StackOverflow 社区的一些帮助下,我能够让我的脏标志实现工作,基于以下示例:http://www.knockmeout.net/2011/05/creating-smart-dirty-flag-in-knockoutjs.html

它完全符合我的要求,除了一个我不知道如何解决的用例。

基本上,我有一个从数据库中自动填充的选择菜单。这个选择菜单还有一个选项可以对我的后端进行 Ajax 调用,刷新选项列表,更新数据库并返回 result。这就是让我毛骨悚然的地方。

第一种方法效果很好,但是,它必须重新索引并重新应用我的整个 viewModel,并且需要大约 2-3 秒,在具有 16gig 内存和 SSD 的本地计算机上运行。

jsondata.component.available_tags = result.available_tags;
ko.mapping.fromJS(jsondata, viewModel);

第二种方法也有效,而且几乎是瞬时的,但是,它设置了isDirty() 标志,我想避免这种情况,因为这些数据已经来自数据库,我不需要保存它。我也不能使用isDirty.reset() 方法,因为如果在我单击菜单选项更新available_tags 之前,isDirty 是由其他东西设置的,它也会重置它。我也想避免。

viewModel().component.available_tags(result.available_tags);

我的问题是:使用第一种方法,我可以使用 ko.mapping.fromJS() 对特定元素而不是整个数据集强制刷新 UI 吗?或者,使用第二种方法,我可以避免在更新available_tags 时设置isDirty 标志吗?扭曲的是我仍然需要将available_tags 保留为可观察的,因此选择菜单会自动生成/更新。

更新:我能够使用

更新单个元素的映射
ko.mapping.fromJS(result.available_tags, {}, viewModel().component.available_tags);

但那立即掀起了isDirty的旗帜......啊

【问题讨论】:

  • 我认为解决方案的关键是 1)不要将您的整个视图模型基于一个 ko.mapping.fromJS(),2)利用映射选项,尤其是 @ 987654322@ 以避免对实际上没有改变的事物进行不必要的重建和 3) 将视图模型分成两个部分:一个与脏标志没有连接的“操作”部分和一个带有脏标志的“用户数据”部分.
  • 当我第一次开始集成 ko.mapping 时,我的性能受到了巨大的打击,结果我需要非常有选择性地选择哪些属性变成 observables 以节省内存。
  • @Tomalak:虽然不完全是一个解决方案,但它对我帮助很大。我从viewModel 中剥离了很多绒毛,并将isDirty() 标志直接附加到我关心的仅有的两个属性上,而不是它们的父级。请提交作为答案,以便我可以解决。感谢您的帮助。
  • 嘿,既然你最终完成了所有的工作(也有“好”和“坏”的代码示例!)你为什么不这样做并写一个很好的答案来说明问题和你的解决方案?我所做的只是推动你一点。我会在你身边为你投票(如果我看到可以改进的代码,也可能会提供更多提示)。

标签: javascript knockout.js knockout-mapping-plugin


【解决方案1】:

除了我完全同意 Tomalak 的建议之外,也许 toJSON 方法可以在您不想拆分模型的类似情况下为您提供帮助。如果您的脏标志实现使用 ko.toJSON 作为散列函数,就像 Ryan Niemeyer 所做的那样,您可以为您的模型(脏标志处于活动状态)提供一个 toJSON 方法,您可以在其中执行以下操作:

function MyObjectConstructor() {
    this.someProperty = ko.observable();
    this.somePropertyNotUsedInDirtyFlag = ko.observable();
}
MyObjectConstructor.prototype.toJSON = function () {
    var result = ko.toJS(this);
    delete result.somePropertyNotUsedInDirtyFlag;
    return result;
};

请注意,这也用于在其他一些情况下序列化对象,例如 ajax 调用。它通常是一个方便的函数,用于在在不同的上下文中使用对象之前从对象中移除计算对象等。

【讨论】:

    猜你喜欢
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    • 1970-01-01
    • 2019-02-19
    相关资源
    最近更新 更多