Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Im not really sure if Im understanding correctly the way observables work and how to get references from mounted tags. I have a component. Within this component we have a component and a component. The purpose is to avoid coupling between components. Because of that, I would like that my search component triggers an event when a search is done(a button is clicked). This event should be caught by the component which will filter the collection data based on the search.

The index.html file load the tag by using:

index.html

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

The page is defined as follow:

page.js

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

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

The component script is briefly defined like:

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

How can I make the component observe for that event?

To me it seems that I should be able to get references from search tag and collection tag in the page.js. By doing so I could connect the events like follow:

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

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

Right now I cannot make it work like that.

At the point of execution, searchComponent and collectionComponent are not defined.

I tried also getting references of these component by using this.searchTag and this.collectionTag instead of mounting them but at the time the code is executed, the components have not been mounted and so I dont get a reference to them.

Any ideas to make it work?

like image 353
kitimenpolku Avatar asked Jul 15 '15 15:07

kitimenpolku


2 Answers

Inspired by the answer given by @gius, this is now my preferred method for sending events in RiotJS from one tag to another.. and it is great to work with!

The difference from @gius approach being that, if you use a lot of nested tags, passing a shared Observable to each tag falls short, because you would need to pass it again and again to each child tag (or call up from the child tags with messy this.parent calls).

Defining a simple Mixin, like this (below), that simply defines an Observable, means that you can now share that in any tag you want.

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

Add this line to your tags..

this.mixin(SharedMixin);

And now, any tag that contains the above line can fire events like..

this.observable.trigger('event_of_mine');

..or receive events like this..

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

See my working jsfiddle here http://jsfiddle.net/3b32yqb1/5/ .

like image 77
John Leach Avatar answered Oct 05 '22 11:10

John Leach


Try to pass a shared observable to both tags.

var sharedObservable = riot.observable();

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

And then in the tags, just use it:

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

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

EDIT: Or even better, since your search and collection tags are child tags of another riot tag (page) (and thus you also don't need to mount them manually), you can use the parent as the shared observable. So just trigger or handle events in your child tags like this:

this.parent.trigger('myEvent');

this.parent.on('myEvent', function() { ... });
like image 30
gius Avatar answered Oct 05 '22 11:10

gius