RiotJS - 如何使用 Observable 模式在子标签之间传递事件?

RiotJS - How to pass events between subtags using Observable pattern?

我不太确定我是否正确理解了可观察对象的工作方式以及如何从挂载的标签中获取引用。我有一个 组件 。在这个组件中,我们有一个 组件 和一个 组件。目的是避免组件之间的耦合。因此,我希望我的 搜索组件 在搜索完成(单击按钮)时触发一个事件。此事件应由 组件 捕获,它将根据搜索过滤 collection 数据。

index.html 文件使用以下方式加载标签:

index.html

riot.mount(".content", "page", null);

页面定义如下:

page.js

<page>
    <!-- Search tag controls -->
    <search id="searchTag"></search>

    <!-- Collection data to display -->
    <collection id="collectionTag"></collection>
</page>

组件脚本的简要定义如下:

search.js

var self = this;
riot.observable(self);

<!-- This function is called when the user click on the button. -->
self.filtering = function()
{
    <!-- We get data from inputs -->
    var info = Getting data from inputs;

    <!-- Trigger the event hoping that someone will observe it -->
    self.trigger("filterEvent", info);
}

如何让 组件 观察该事件?

对我来说,我似乎应该能够从搜索标签collection标签中获得参考page.js。通过这样做,我可以像下面这样连接事件:

searchComponent = riot.mount('search');
collectionComponent = riot.mount('collection');

searchComponent.on('filterEvent', function()
{
   <!-- Trigger function to filter collection data -->
    collectionComponent.trigger('filterData');
});

现在我不能让它像那样工作

在执行时,searchComponent 和 collectionComponent 未定义

也尝试使用 this.searchTagthis.collectionTag 获取这些组件的引用,而不是挂载它们,但是在执行代码时,这些组件还没有挂载 所以我没有提到它们。

有什么想法可以让它发挥作用吗?

首先我不明白你的文件结构!

在你的位置我会更改文件名:

page.js --> page.tag

search.js --> search.tag

而且我在 search.js 代码中没有看到您的搜索标签。


所以我没有看到您的 Collection 标记文件...

你确定这个人使用这个代码吗? riot.observable({self|this}); 因为接收事件的是他。

对我来说,当我在浏览器中使用 Riot.js(2.2.2) 时,如果我使用 searchComponent = riot.mount('search'); searchComponent 将是未定义的

但使用此代码,您可以保存您的 mont 标签参考:

var searchComponent ={};
riot.compile(function() {
    searchComponent = riot.mount('search')[0];
});

尝试将共享的可观察对象传递给两个标签。

var sharedObservable = riot.observable();

riot.mount('search', {observable: sharedObservable}); // the second argument will be used as opts
riot.mount('collection', {observable: sharedObservable});

然后在标签中,使用它:

this.opts.observable.trigger('myEvent');

this.opts.observable.on('myEvent', function() { ... });

编辑: 甚至更好,因为您的 searchcollection 标签是另一个防暴标签 (page) 的子标签(因此您也不需要手动安装它们),您可以使用父对象作为共享的可观察对象。因此,只需像这样触发或处理子标签中的事件:

this.parent.trigger('myEvent');

this.parent.on('myEvent', function() { ... });

受@gius 给出的答案的启发,现在这是我在 RiotJS 中将事件从一个标签发送到另一个标签的首选方法。使用起来很棒!

与@gius 方法的不同之处在于,如果您使用大量嵌套标签,将共享 Observable 传递给每个标签是不够的,因为您需要一次又一次地将它传递给每个子标签(或调用从具有混乱 this.parent 调用的子标签开始)。

定义一个简单的 Mixin,就像下面这样,它简单地定义了一个 Observable,这意味着您现在可以在任何您想要的标签中共享它。

var SharedMixin = {
observable: riot.observable()
};

将此行添加到您的标签中..

this.mixin(SharedMixin);

现在,任何包含上述行的标签都可以触发事件,例如..

this.observable.trigger('event_of_mine');

..或收到这样的事件..

this.observable.on('event_of_mine',doSomeStuff());

在这里查看我的工作 jsfiddle http://jsfiddle.net/3b32yqb1/5/ .

另一种选择是使用全局可观察对象,这可能并不总是最佳做法。当满足某些条件时,我们使用 Riot 的内置条件来挂载标签,而不是直接通过 JS 挂载它们。这意味着标签彼此独立。

例如,单个可观察对象可用于管理所有通信。这本身并不是一个有用的示例,它只是为了演示一种技术。

比如在一个普通的JS文件中如main.js:

var myApp = riot.observable();

一个标记文件可能会触发更新。

var self = this;
message = self.message;
myApp.trigger('NewMessage', message);

任意数量的其他标记文件可以侦听更新:

myApp.on('NewMessage', function(message) {
  // Do something with the new message "message"
  console.log('Message received: ' + message);
});

也许有点矫枉过正但很简单。让 riot 自我观察

riot.observable(riot);

所以你可以使用

riot.on('someEvent', () => {
  // doing something
});

在标签中,并且

riot.trigger('someEvent');

在另一个。

用全局变量不好,用一个已经存在的或许可以接受。