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

时间:2015-07-15 15:45:03

标签: javascript web-component riot.js

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

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);
}

如何让组件观察该事件?

对我而言,似乎我应该可以从 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来获取这些组件的引用,而不是安装它们,但在执行代码时,组件尚未安装所以我没有得到他们的参考。

任何让它运作的想法?

4 个答案:

答案 0 :(得分:14)

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

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)的子标记(因此您也不需要手动安装它们),可以使用parent作为共享的observable。因此,只需触发或处理子标记中的事件,如下所示:

this.parent.trigger('myEvent');

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

答案 1 :(得分:2)

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

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

  

page.js - &gt; page.tag

     

search.js - &gt; 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];
});

答案 2 :(得分:0)

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

例如,可以使用单个observable来管理所有通信。这本身并不是一个有用的例子,只是为了展示一种技术。

例如,在一个普通的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);
});

答案 3 :(得分:0)

也许矫kill过正,但简单。让riot自我观察

riot.observable(riot);

因此您可以使用

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

riot.trigger('someEvent');

在另一个。

使用全局变量不好,但是使用已经存在的变量也许可以接受。