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

kit*_*lku 5 javascript web-component riot.js

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

index.html文件使用以下方法加载标记:

的index.html

riot.mount(".content", "page", null);
Run Code Online (Sandbox Code Playgroud)

该页面定义如下:

page.js

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

    <!-- Collection data to display -->
    <collection id="collectionTag"></collection>
</page>
Run Code Online (Sandbox Code Playgroud)

组件脚本简要定义如下:

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);
}
Run Code Online (Sandbox Code Playgroud)

如何让组件观察该事件?

对我来说,似乎我应该能够从page.js中的搜索标签集合标签中获取引用.通过这样做,我可以连接如下事件:

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

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

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

在执行时,未定义searchComponent和collectionComponent.

尝试通过使用this.searchTagthis.collectionTag不是安装它们来获取这些组件的引用,但是在执行代码时,组件尚未安装,因此我没有得到它们的引用.

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

giu*_*ius 14

尝试将共享的observable传递给两个标记.

var sharedObservable = riot.observable();

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

然后在标签中,只需使用它:

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

this.opts.observable.on('myEvent', function() { ... });
Run Code Online (Sandbox Code Playgroud)

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

this.parent.trigger('myEvent');

this.parent.on('myEvent', function() { ... });
Run Code Online (Sandbox Code Playgroud)


小智 14

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

与@gius方法的不同之处在于,如果使用大量嵌套标记,将共享Observable传递给每个标记都不合适,因为您需要将它一次又一次地传递给每个子标记(或从子标记中调用)与凌乱的this.parent电话).

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

var SharedMixin = {
observable: riot.observable()
};
Run Code Online (Sandbox Code Playgroud)

将此行添加到您的代码中..

this.mixin(SharedMixin);
Run Code Online (Sandbox Code Playgroud)

现在,包含上述行的任何标记都可以触发像..

this.observable.trigger('event_of_mine');
Run Code Online (Sandbox Code Playgroud)

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

this.observable.on('event_of_mine',doSomeStuff());
Run Code Online (Sandbox Code Playgroud)

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


Beb*_*ber 2

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

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

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 将是未定义的

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

var searchComponent ={};
riot.compile(function() {
    searchComponent = riot.mount('search')[0];
});
Run Code Online (Sandbox Code Playgroud)