riot-js

Open full view…

Way to call trigger observable from outside of Riot?

andrehazelwood
Wed, 10 Feb 2016 00:28:25 GMT

I just discovered Riot and really like what I'm seeing. One of the things that I can't quite see how could be done, would be to call into Riot from an external library or function, and trigger an observable within Riot. For example, if a page hosted in an iframe wanted to update an observable for another Riot component on a parent page, or vice-versa. Any thoughts on how this would be accomplished? Thanks.

Nino Porcino
Wed, 10 Feb 2016 08:31:24 GMT

HTML elements that are also Riot tags can be accessed via the hidden/undocumented property `_tag`. So if you can access the element you can do something like this: ``` var myel = document.querySelector("#myel"); // or similar; var riotTag = myel._tag; riotTag.trigger("your-riot-event"); ```

andrehazelwood
Wed, 10 Feb 2016 13:12:15 GMT

Any way this could be added to the documentation, or at least come up with a way to make this a supported way?

andrehazelwood
Wed, 10 Feb 2016 13:57:22 GMT

In case this helps anyone, apparently you can make any object observable. So in my index.html file I made a new object: var bus = riot.observable() I can then trigger events on this object or subscribe to events from any of my internal tags by referencing this global object. bus.on('event-name', function() { // handle event here }) // Trigger an event either outside of tags or in a tag. bus.tigger('event-name') Quite slick. This article came in handy: http://streamdata.io/blog/exploring-riot-js-part3-2/

Nino Porcino
Wed, 10 Feb 2016 14:11:01 GMT

yes that can be another way, the only drawback is that `bus` has to be declared globally and assumed to be there. Btw, I think the correct syntax is `riot.observable(bus)`, not `var bus = riot.observable()`

andrehazelwood
Wed, 10 Feb 2016 21:32:04 GMT

Nino, In this case, you're correct, bus has to be external. The only way I was able to get it to work was the way I listed because I am communicating from outside of Riot into Riot and several embedded tags. I'm open to other thoughts or suggestions. http://plnkr.co/edit/kS7hnuY0fpdBh5bErLqV?p=preview Also, in order for any of this to work there must be at least one html element within each tag.

warfee
Thu, 25 Feb 2016 12:41:29 GMT

Have you tried a mixin with observerable declared inside, that can be shared by all tags. Then you just trigger the event on all tags sharing the mixin.

crisward
Sat, 27 Feb 2016 00:32:18 GMT

I developed a toaster tag (the kind that does pop up messages). I also wanted to use it from other frameworks. The way I did this was, in the mount event, i added `this.root.trigger = this.trigger` This copies a reference to the tags trigger to the domnode. So to use it from elsewhere I can use ``` document.querySelector('toaster').trigger('add',{message:"Something happend"}) ``` Then within the toaster tag you can just use ``` this.on('add',function(opts){ //do something with opts.messsage }) ``` Not sure how common this pattern is, but it's worked quite well. Also not sure how close it fits in with your use case.

simondouglas
Wed, 14 Dec 2016 01:37:25 GMT

I don't this longer works in riot < 3. The plunkr, doesn't work.

dongood
Sun, 19 Feb 2017 02:28:59 GMT

I created a common module as follows. Note that I hate "magic numbers" so I added the events object *after* calling `new Pubsub()`: --- (function (window, undefined) { "use strict"; function Pubsub() { riot.observable(this); } window.pubsub = new Pubsub(); window.pubsub.events = { sidebar: { open: 'pubsub.events.sidebar.open', enabled: 'pubsub.events.sidebar.enabled' }, navbar: { menu: 'pubsub.events.navbar.menu', title: 'pubsub.events.navbar.title' }, dataUpdated: 'pubsub.events.dataUpdated' }; })(window); --- Then you can trigger from anywhere in JavaScript (not just Riot tags): --- pubsub.trigger(pubsub.events.sidebar.enabled, sidebar); --- And you can respond to events from anywhere: --- pubsub.on(pubsub.events.sidebar.enabled, function (truefalse) { // code here }); ---