How does the event translation work in a Giraffe router? - backbone.js

I just discovered the approach to router events in Giraffe. It is possible to trigger application events as follows:
routes: {
'childView/:name': 'route:childView'
// 'someHashLocation/:andItsParams': 'some:appEvent'
},
Since normally routing events are processed by callback functions, I wonder what does it take to trigger these routing events from a non-Giraffe Backbone application? Any issues that you see with this kind decoupling the router from application modules?

Since normally routing events are processed by callback functions, I
wonder what does it take to trigger these routing events from a
non-Giraffe Backbone application?
Anything with a reference to a router can cause routing events, e.g.:
var app = new Giraffe.App({routes: {'post/:id': 'route:post'}});
// Trigger a route with an app reference
app.router.cause('route:post', 42); // => location changes to #post/42
// => 'route:post' triggered on `app`
Giraffe.Router#cause is like Backbone.Events#trigger with the addition of navigating to the corresponding route, if one exists, and the router triggers the event on the app, not itself.
Anything with the app reference can listen for a routing event:
// Handle the route from outside the Giraffe app
app.on('route:post', function(id) {...});
// Other `Backbone.Events` instances can listen to the Giraffe app
var myOtherApp = new Backbone.View;
myOtherApp.listenTo(app, 'route:post', function(id) {...});
The app also acts as a convenient event hub beyond routing events. All Giraffe objects have a reference to this.app (if one has been created) and support for the shortcut appEvents bindings.
Any issues that you see with this kind decoupling the router from application modules?
(I'm one of the authors) We at our company and I in my personal experience have not found this to be a problem, but one can imagine situations where this event-based system fails to provide the level of coordination needed. We've considered improving route handling with functionality like filters but haven't found the time for it yet. If you have suggestions we'd love to hear them!

Related

"Synchronise" loading of components in a page

I have an Ionic 1.3 mobile application in which I am using Angular 1.5. Each page is comprised of one or more Angular components and each one of these components may in turn contain other components, thus creating a component tree within the page.
The problem I have is that some of these components might require data from the server, which are loaded in the component's $onInit function. Since this data is retrieved asynchronously (and there might be delays) the result is for the components to appear one after the other in the page (depending on when each one manages to initialise) which doesn't make for a very "native" mobile experience. What I would like to do is find a way to know when all components have finished loading so that I can display the page only after it is really ready (all components are fully rendered).
My original idea was to "register" each component with a service when its controller initialises and then notify the service that the component is ready once the data is loaded. The service can then be responsible for showing the page when all components are ready. My problem with doing this is that components seem to initialise sequentially (ie. component1's controller initialises and then $onInit executes, then component2's controller initialises and $onInit executes, etc.) which means that my service can't really know how many components it is waiting for. Not only that, but also a component's children controllers initialise and their $onInit methods execute after the parent component has finished initialising, which means that the component also can't keep track of whether its children have initialised or not.
An alternative would be to hard-code the number of components somewhere in the page and pass it to the service through the page controller so that it knows how many components to wait for without the components needing to register themselves, but ideally I would like something a bit more maintainable (ie. something that doesn't require me to keep track of components and keep this number up to date myself).
Can anyone think of any other way I can keep track of when my page is ready using either Angular or Ionic? Ideally it would be something that can also be ported to Angular2 / Ionic2 since I expect the app to get upgraded at some point, but any suggestion is welcome.
You can try to use resolve in ui.router or ngRoute:
angular.module('app', ['ui.router'])
.config(['$stateProvider', function($stateProvider) {
$stateProvider.state('mainstate', {
url: 'your-url'
,templateUrl: 'yout_template.html'
,controller: 'YourController'
,resolve: {
yourFirstData: ['serviceDeps', function(serviceDeps){
return serviceDeps.getFirstData();
}]
,yourSecondData: ['serviceDeps', 'yourFistData', function(serviceDeps, yourSecondData){
return serviceDeps.getSecondData(yourFirstData);
}
}
}
}]);
The resolve will get the data and resolve promises before loading controller.
This is an ideia.

Using Backbone.js how i can ensure that all the app is loaded before any user interaction

I have a web page that was developed using Backbonejs and Marionettejs.
I have a lot of views, the problem is when i enter for the first time to the app or i reload the webpage if i interact (make any click) in the page i think the page stops loading and i receive in the console error that can't navigate.
I tried to resolve this issue using requirejs or ensurejs but I had no success.
There is a way to ensure the web page is loaded completely befor the user send an event or prevent the user to make that?
When you say "page loaded" do you mean the DOM or actually downloaded the files?
To me it sound more like a routing issue. Try to double check if all the callback functions of the marionette router are specified and also the route you want to
navigate to is avaiable.
If you mean the DOM, every Marionette View has 2 callbacks about DOM rendering. The first one: onRender is called when the new HTML is ready to go in the DOM, but not appended yet and onDomRefresh is called when the new HTML is actually in the DOM. So, if you need to know when the page is rendered use onRender, when you also have to know if is in the DOM use onDomRefresh.
Like this:
var test = Marionette.ItemView.extend({
onRender: function() { ... },
onDomRefresh: function() { ... }
})
Require is to load files in a asynchronos way. You could definitely improve the architecture of your app.
Please add more details so i can give u a more specific answer.
I have also made a skeleton of a Backbone / Marionette / Require app. Check it out at: https://github.com/LucaMele/skeleton-marionette-require-gulp

AngularJS: Get Scope of Dependent Module

Getting The Scope of Another Module to Dispatch Events;
Acyclical Directed Communication Network
EDIT: THIS QUESTION IS UNDER REFORMATION.
Intention
What I'm looking to do is fairly straight-forward. I have an Application Core module which looks like this:
var app, application = app = angular.module('app', ['session', 'validation', 'summary', 'participants', 'ngRoute']);
...where each dependency is a module with its own $rootScope (SEE COMMENTS BELOW).
I intend on implementing a Mediator -- not an EventHub. EventHubs are simply a skinny-waist to which subsystems can publish and subscribe to broadcast channels on a specific medium. What I want is a true Mediator -- which, according to GoF, actually manages security of how and where modules communicate, in a unicast model.
That said, I cannot solely rely on using $rootScope.$broadcast/$emit as this will allow any & every module to listen to events from other modules -- without any control or intervention (mediation) from a centralized mechanism.
Problem
The problem arises when there is one module firing an event, say, 'excuseFileLog' and other listening for 'excuseFileLog' -- while the mediator is listening to this event from one module and dispatching it for another. Mediator is listening for one module to say "please excuse the 'FileLog'" and telling another that "an excuseFile has been logged". This is very semantic, as excuse, File, and Log are each, both a verb and a noun. So when Mediator dispatches this same event that it, itself, is listening for -- we enter an Infinite Loop:
// mediator is the sole medium for channels
mediator.on('excuseFileLog', function(){
mediator.fire('excuseFileLog');
});
Solvent
Put simply, I need to be able to access each module's $rootScope and fire events on that module alone -- hopfully, without the need of creating a service that will have to be injected into every module; which will encumber the developer with having to remember to implement the service and creating slightly tighter coupling. If a service is involved, then I may as well implement my own mediator/eventing-system, as apposed to leveraging Angular's eventing system. As the rest of the team is somewhat novice, I would prefer to keep 'chores' to a minimum.
Any help is very appreciated :)

Online Resources for Google Analytics Event Tracking for Backbone Application

I was trying to find some resources online for using Google Analytics' event tracking functionality in a Backbone application, and the only one that I was able to find was a blog post from airbnb, which uses CoffeeScript. Does anyone know of any resources for a regular javascript Backbone app? I have not used the event tracking functionality before, so basic resources are appreciated ...
Thank you!
You can just push events into the queue whenever is appropriate.
So, for example, we have a single paged app, for which we want to track page views, although we're never reloading the page.
To achieve this goal, we attach on all of our router events a listener which pushes each new page view into the _gaq stack. (This is greatly simplified.)
router.on("route", function(page) {
_gaq.push(['_trackPageview', page]);
});
This will push the page argument into the Google Analytics tracking stack. Just make sure that you've set up Google Analytics prior to this call.
For events, for example, we sometimes want to track a button being pushed. Therefore, we just make a _trackEvent push into the queue with the object containing the details of what we're pushing.
Instead of putting a ton of _gaq.push code on your page, I would recommend you to make a function available throughout your app that abstracts this functionality, such as:
var track = function(event, payload){
_gaq.push[event, payload];
};
This will isolate you from changes to the Analytics API, as well as allow you to add other reporting locations to your tracking events easily.

Changing my backbone.js router

I have a web application with require.js, backbone.js and jquery.
The brief structure of the app is as follows:
There are 2 sections on the screen (toolbar and main content below).
There are multiple components (address management, event management), each triggered by a hash fragment change and require a
page transition.
There is one backbone.js router. It's the heart of the application. The router is activated with a new hash fragment (manually entered,
back button, menu item selection).
Up until now, in the router, I made the page transition, I DIRECTLY called the controller ("view" in backbone) of the selected component.
So there's a CENTRAL handling of controller calling.
But this has to change now to a DISTRIBUTED handling. I now need to respond to a new hash fragment from two different places: From the toolbar component and from router.
So my idea is to exchange the direct controller calling mechanism with pub sub. Now MULTIPLE components could register for a special action and the router just "fires the event".
I searched around and found Chaplin (https://github.com/moviepilot/chaplin), a backbone.js example application.
The developers of Chaplin seem to have a similiar thing called "ApplicationView" (https://github.com/moviepilot/chaplin#toc-router-and-route):
"Between the router and the controllers, there’s the ApplicationView as
a dispatcher."
Is there anyone who has already this kind of architecture and can tell me his experience with this or has anybody solved this in another way?
I've used a similar, though maybe less complex, architecture in this project. I give a pretty good explanation in this answer to a related question. The quick overview:
I manage app-wide events that change the application state using a singleton State model that works similarly to Chaplin's pub/sub architecture. This is just a basic Backbone model, with some added methods to deal with serializing and deserializing attributes as strings, so they can be set in the URL.
Application components that change the application state in response to user interaction or other input do so by setting properties on app.state.
Components that need to update when the application state changes do so by binding to change events on app.state (it looks like this is exactly the way Chaplin's mediator works, though they renamed the methods to fit the pub/sub paradigm).
I treat my routers like specialized views that update the address bar and respond to user input in that area. Changing the address (manually or by clicking on a link) causes the router to set() the necessary changes on the app.state model, and everything else updates accordingly.
I hope that's helpful - I think it's a little simpler than the Chaplin approach.

Resources