5

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

index.html 文件通过以下方式加载标签:

索引.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>

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

搜索.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

5 回答 5

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() { ... });

编辑:甚至更好,因为您的searchandcollection标签是另一个 riot 标签 ( page) 的子标签(因此您也不需要手动安装它们),您可以将父标签用作共享的 observable。因此,只需触发或处理子标签中的事件,如下所示:

this.parent.trigger('myEvent');

this.parent.on('myEvent', function() { ... });
于 2015-08-19T13:20:17.760 回答
14

受@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/

于 2015-08-24T11:12:33.633 回答
2

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

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

page.js --> page.tag

search.js --> search.tag

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


所以我没有看到你的收藏标签文件......

你确定这个使用这个代码吗? 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];
});
于 2015-07-31T14:45:47.150 回答
1

另一种选择是使用全局可观察对象,这可能并不总是最佳实践。我们使用 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);
});
于 2017-09-12T05:26:07.020 回答
0

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

riot.observable(riot);

所以你可以使用

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

在标签中,并且

riot.trigger('someEvent');

在另一个。

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

于 2018-09-27T08:58:16.543 回答