【问题标题】:How should custom elements in knockout communicate with their collaborators?淘汰赛中的自定义元素应该如何与其合作者沟通?
【发布时间】:2015-03-07 17:39:08
【问题描述】:

我很难找到一种让自定义元素与周围环境交流的好方法。到目前为止,我的 google-karma 很低,我还没有找到任何描述 Knockout 中自定义元素的良好架构的东西。

与往常一样,什么才是好的架构取决于 ;-)

更新: I created a fiddle trying to explain what I have in mind.

就我而言:

  • 我希望自定义元素真正具有自主性。
  • 它应该在添加到视图时正常工作,没有错误。
  • 它根本不应该与任何服务或任何其他外部组件直接通信。

给定一个带有一个保存按钮的自定义元素,只有在某些事情发生变化后才应该激活它,我们可以像这样传递一个协调器:

function CustomElement(params) {
    var coordinator = params.coordinator;
    var enabled = this.enabled = ko.observable(false);

    this.save = function() {
        coordinator.save();
    }

    coordinator.onchange(function(hasChanges) {
        enabled(hasChanges);
    });
}

父视图模型定义协调器的地方:

function ParentView() {
    this.coordinator = new CustomElementCoordinator();
}

并通过参数传递:

<custom-element params="coordinator: coordinator"></custom-element>

那我在想协调器应该和自定义元素在同一个目录下定义:

custom-elements
    - custom-element
        - coordinator.js
        - model.js
        - template.html

你怎么看?我是在做某事,还是我处理不当?

【问题讨论】:

  • 但是……但是……为什么?对我来说,听起来您想将 MVC 控制器(例如,在 Angular 中找到)实现为 KO(MVVM);而在 KO 中,视图已经这样做了(例如,它通过视图将模型的值传达给组件;更重要的是,它能够直接修改您的模型,因此建议的“onchange”和“save”总是在 observables 中隐式执行) .所以在我看来,这只是一个不必要的额外步骤......
  • @Tyblitz,您将如何设计自定义元素以相互通信或任何其他组件?至于为什么,我不希望 element-a 耦合到 element-b。如果我想要一个视图上有两个 element-a 实例,我不希望来自一个的事件干扰另一个。假设其中三个元素是不同的过滤器,一个元素是列表,主视图模型引用执行查询并返回过滤结果的实际服务。假设该列表也用于其他视图,但具有不同的服务且没有过滤器。
  • 基本上我会使用一个集中的主虚拟机作为协调器,而不是为每个组件构建一个,我认为这与top-down nature of JS/DOM/KO 很相配。例如,查看this fiddle,它使用了一个列表组件和两个过滤器组件,它们都使用相同的模板但修改了数组。我希望它能准确地描述你描述的情况
  • 有趣!让我们比较一下笔记。 I created a fiddle where I added some extras to show more closely what I have in mind。一般来说,我认为在一个视图中声明一个可观察对象,然后在另一个视图中绑定它是不好的做法。使用 observables 进行组件间通信也感觉不对。在小提琴中,我尝试消除组件之间的耦合,并在它们自己的类中形式化通信契约。
  • 这看起来非常非常整洁。我确实有一些想法。或许我们应该继续in this topic我开始了,而不是乱七八糟的cmets(如果这变成了东西,你可以在OP中参考它)。 (回复你上一条评论也有)

标签: knockout.js custom-element


【解决方案1】:

在关于跨组件通信的相当大的辩论中,我赞同越简单越好的观点。

DOM 元素之间最古老、最可行的通信方式是什么(最终会变成哪些组件)?为什么,当然是事件

您的组件应该使用 Knockout 来处理内部状态。但是,添加事件 API 可以在兼容性方面创造奇迹。如果有一天你的整个应用程序都不是由 Knockout 驱动的(相信我,这很可能会发生),你的组件不会完全没用。

很简单:

$(window).on("myEvent.myComponent", this.handleMyEvent) //listen to the world
$("#myNode").trigger("finished.myComponent", ["param1", "param2"]) // talk to the world

如果您想在注入组件时抓住它的节点元素,请查看createViewModel 样式,根据这个问题:How to access custom element in a Knockout component?

【讨论】:

  • 我真的不喜欢基于字符串的事件。我对此进行了试验,发现字符串本身可以在自定义元素之间引入硬耦合。我发现当我们删除另一个自定义元素时,一个自定义元素可能会停止工作。
  • 在事件名称或函数名称中选择字符串:)
猜你喜欢
  • 2016-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
相关资源
最近更新 更多