可以在 KNOCKOUT js 中将依赖跟踪与行为分开

Possible to separate dependency tracking from behavior in knockout js?

本文关键字:跟踪 依赖 KNOCKOUT js      更新时间:2023-09-26

在我当前的项目中,我们有一个概念模型,在一个视图模型中包含许多可观察量和可观察数组以及修改数据的行为。在项目的后期,我们希望将一个"屏幕"上的信息分成两个屏幕。这导致了如何拆分视图模型,以便每个屏幕只处理其数据的行为。最终发现这太难拆分了,我们将相同的视图模型绑定到两个"屏幕"。

我想知道是否有办法让一个单独的"模型"对象存储可观察/可观察数组,允许您进行依赖跟踪。这样,您就可以共享包含数据和依赖项跟踪的模型对象。之后,每个屏幕的 viewModel 是否包含特定于该屏幕的行为?

我知道我可以有一个包含可观察对象的单独模型对象,并使用"with"将该模型绑定到两个视图模型中,但我想知道是否有另一种方法。

是的,有。

从挖空版本3.2.0开始,您可以使用"挖空Web组件">

让我们想象一下你想制作一个"徽章",像这样

<div class="badge">
  <h1>Name: <span>Joe Blogs</span></h1>
  <h3>Position: <span>Engineer</span></h3>
</div>

现在,让我们从可重用的角度看一下。

您可能想要动态更改的位是名称和位置

如果你已经在Knockout中使用这些,你可能会有如下的东西:

<div id="thebadge" class="badge">
  <h1>Name: <span data-bind="text: name">xxx</span></h1>
  <h3>Position: <span data-bind="text: position">xxx</span></h3>
</div>

然后你实际上可能会将它与 Knockout 一起使用,如下所示:

var BadgeViewModel = { 名称: ko.observable('Joe Blogs'(, 职位: 可观察("工程师"(};

然后,您可以使用如下所示的内容将其应用于您的 html:

ko.applyBindings(BadgeViewModel);

注意:我只是在这里做一些事情来演示这个概念

目前为止,一切都好。。。这是经典的做事方式,如果你有这个,把它转换成一个组件一点也不难。

您只需将视图模型和 html 模板组合到一个实体中即可。

因此,对于此处的示例,我们可以使用:

ko.components.register("my-badge", {
  viewModel: function(data) {
    this.name = (data && data.name) || "Not Defined";
    this.position = (data && data.position) || "Not Defined";
  },
  template: '<div id="thebadge" class="badge"><h1>Name: <span data-bind="text: name">xxx</span></h1><h3>Position: <span data-bind="text: position">xxx</span></h3></div>'
});

注册组件后,您可以在 html 标记中使用它的注册名称,如下所示:

<my-badge></my-badge>

您的徽章将出现。

但是,问题是您没有初始化任何数据。

如果查看第二个示例代码中的 VM,将看到我们有一个传递给模型的"data"对象,并且我们检查它以查看它是否存在,以及我们的名称和位置属性是否存在。

如果他们不这样做,我们就使它们等于"未定义">

要传入参数,只需使用 params 属性,如下所示:

<my-badge params="name: 'Joe Blogs', position: 'engineer'"></my-badge>

这将使名为名称和位置的属性可供组件使用。

重复使用它很容易,只需重复标记,例如:

<my-badge params="name: 'Joe Blogs', position: 'Engineer'"></my-badge>
<my-badge params="name: 'Fred Blogs', position: 'Scientist'"></my-badge>
<my-badge params="name: 'Andrew Blogs', position: 'Developer'"></my-badge>
<my-badge params="name: 'Tony Blogs', position: 'Manager'"></my-badge>

有更好的方法,如果你阅读了 KNOCKOUT JS 网站上的组件文档,他们建议你使用 requirejs 或其他一些模块加载器来帮助你只在需要时加载 html 块。

但是,只需使用它们一次或两次即可提供可重用的视图,如果您将它们保存在单独的.js文件中,则很容易。