What's the difference between relying on Application's event mixin and Application.vent? - marionette

What's the point of Application.vent in Marionette? The Application object already extends Backbone.Events, so I can write the following:
window.app = new Backbone.Marionette.Application();
app.on("my:event", function() { console.log(arguments); });
app.trigger("my:event");
More easily than:
window.app = new Backbone.Marionette.Application();
app.vent.on("my:event", function() { console.log(arguments); });
app.vent.trigger("my:event");
I've read the source and I can't tell the difference, but that doesn't mean there isn't one, and I'm half-willing to bet there's a good reason it's done the way it is.

While Application.vent's functionality does overlap Application's built-in events, it adds more functionality than just a simple on/trigger event mechanism because it's an instance of Backbone.Wreqr. This adds command events and a request/response mechanism to allow modules to communicate to each other more easily.
It's still just events at the heart of it, but it aims to make inter-module communication a little easier to follow.

Related

What is the best place to put onEnter, onExit callback functionality?

I am creating my first project that uses ui-router.
My project has about 10 views, each with their own controller and state. I am trying to modularise/encapsulate/decouple as best as possible but I am having trouble working out where to put the onExit and onEnter state callbacks.
The first option is to put it in app.js which is currently defining all of my states, however I feel that this would not be a good place as it could cause this file to blow up and become hard to read as more states are introduced and the logic gets more complex.
The second option I looked into was to put it into a controller (I have one for each state), however from researching it doesn't seem to be best practice to do this.
The third option is to create a service that is resolved, however with this option I would end up with either a giant service full of state change functions for each of the states (not decoupled) or an additional service per state which would contain the state change functionality, and I worry that would increase project complexity.
What is the standard way to achieve this?
Are there any other options that I am missing?
Our strategy for this has been to disregard the onEnter and onExit on the state object, because as you are discovering, they feel like they are in the wrong place in terms of separation of concerns (app.js).
For onEnter: we handle setup in an activate() function in each controller, which we manually execute inside the controller. This happens to also match the callback that will get executed in Angular 2.0, which was not an accident ;).
function activate() {
// your setup code here
}
// execute it. this line can be removed in Angular 2.0
activate();
For onExit: We rarely need an exit callback, but when we do, we listen for the $scope $destroy event.
$scope.$on("$destroy", function() {
if (timer) {
$timeout.cancel(timer);
}
});

Windows.UI.WebUI.WebUIApplication versus WinJS.Application

What is the distinction between Windows.UI.WebUI.WebUIApplication versus WinJS.Application?
WinJS.Application is a namespace. WebUIApplication is an object (or a class of object). But consider the following:
WebUIApplication supports the following events:
WebUIApplication.activated
WebUIApplication.resuming
WebUIApplication.suspending
WebUIApplication.navigated
WinJS.Application Namespace defines the following events:
onactivated
oncheckpoint
onerror
onloaded
onready
onsettings
onunload
In particular, why is resuming done with WebUIApplication but not with WinJS.Application, but it seems that activation and checkpoint can be done either way?
Windows.UI.WebUI.WebUIApplication.onresuming = function (args) { ... }; // OK
WinJS.Application.oncheckpoint = function (args) { ... }; // OK
WinJS.Application.onactivated = function (args) { ... }; // OK
WinJS.Application.onresuming = function (args) { ... }; // NOT OK
The APIs you refer to that are in the Windows.* namespace are the actual core of the app model. Everything in WinJS, on the other hand, are wrappers that are intended to simplify that app model where there is value in doing so. For example, most apps need to do some work on the suspending event, and WinJS provides a sessionState object that is automatically saved on suspended and reloaded when the app is relaunched. However, because there's typically no action that WinJS needs to do for resuming, it doesn't wrap that particular event.
The Windows.* (WinRT) APIs, in other words, are the essential core that you have to use to write an app. WinJS is an optional library that is not at all required, but contains many essentials (like controls) that most apps will use anyway.
Typically, then, you'll use the WinJS events for convenience. It's also easy to include resuming in this model: add a handler for the WebUIApplication.oneresuming event, and call WinJS.Application.queueEvent("resuming", ...) which will then route a "resuming" event into the WinJS.Application object. That way you can centralize your handling of application events in one place.
I talk more of the relationship between these in Chapter 3 of my free ebook, Programming Windows Store Apps in HTML, CSS, and JavaScript, Second Edition, currently in preview. See http://aka.ms/BrockschmidtBook2.

Using Promises in AngularJS Views

Mark Dalgleish wrote a nice little article about how to use promises in AngularJS views.
Some people asked questions about this in the comments, but Mark didn't answer them (yet). Because I'm asking me the same question, I will ask on StackOverflow instead to get an answer:
If you use promises in views, how do I handle "loading"/"waiting" indication, because they are async? Does a promise have something like a "resolved" or "withinRequest" property?
How do I handle errors? Normally they would arise in the second callback, but if I use a promise directly in the view I don't handle this case. Is there another way?
Thank you.
EDIT: as of angular v1.2 the resolution of promise in views is not activated by default.
The automatic resolution of promises in a view looks like a handy tool at first but it has number of limitations that need to be understood and evaluated carefully. The biggest issue with this approach is that it is AngularJS who will add callbacks to a promise and we've got little control over it.
Answering your questions:
1) As indicated, it is ultimately AngularJS who will add a success / error callbacks so we don't have much control here. What you could do is to wrap the original promise into a custom one that would track resolution. But this kind of deft the whole purpose of saving few keystrokes. And no, there is no things like 'resolved'. In short - there is no universal mechanism for tracking progress that would work for all promises. If your promises are $http-based you might use interceptors or pendingRequests property to track request in progress.
2) You can't. Once again, it is AngularJS that adds a handler inside the $parse service and it looks like this: promise.then(function(val) { promise.$$v = val; }); (see code here). You can see that only a success callback are added so all the failures are going to be silently ignored.
Those are not the only limitations of the automatic promise resolution in the view. The other problem is that promises returned by a function won't be resolved correctly. For example, if you would rewrite an example like so:
myModule.controller('HelloCtrl', function($scope, HelloWorld) {
$scope.messages = function() {
return HelloWorld.getMessages();
}
});
and try to use the following markup:
<li ng-repeat="message in messages()"></li>
things would work as expected, which might come as a surprise.
In short: while the automatic resolution of promises might seem like a handy shortcut it has number of limitations and non-obvious behaviors. Evaluate those carefully and decide if saving few keystrokes are worth it.

Node.js, restify and proper routing

I'm still wrapping my head around Node, but I have a very simple question. I see a lot of node examples where people are declaring their routes and all their logic in a single app.js file (or sometimes splitting them off into subfiles).
My question is basically: is it better to keep all your route declarations in the app or bootstrap a generic route that maps to your file structure. This may seem like a primitive question but my goal is to grasp what's most efficient within node.
I'm currently building an API handler with Restify but I have another app that uses Express (so this question will likely answer both questions).
In my route I can either declare a single route bootstrap like so:
app.all('/api/:package/:controller', function(request, response) {
var controller = require(
'../' + request.params.package + '/api/' + request.params.controller
);
controller.index(request, response);
response.end();
});
This basically accepts all calls from the API and targets the proper api controller. Alternatively I can declare each route individually or perhaps even write an loop that goes through each of my controllers and declares them on init. So:
for (var i in packages.controllers) {
app.all('api/' + package + '/' + controllers[i].name, function(request, response) {
var controller = require(
'../' + request.params.package + '/api/' + request.params.controller
);
controller.index(request, response);
}
}
packages.controllers being an array of all possible controllers. Note the above code is not accurate, I have an HMVC folder structure so the code is a bit more complicated than the above. But you get the point.
I'm wondering what the consequences of either are and if it really matters at all?
Thanks!
I would not recommend a single app.js at all. You will end up with a 5,000+ line file which is a nightmare to maintain.
The largest issue I see with your snippet is that even though require() gets cached, it has to perform a synchronous IO request. It's just a bad habit to get into.
Similar to what Don recommends, I have had the best luck splitting out routes into modules which export a single function which accept an instance of the app. You can think of it as "decorating" the app instance:
// app.js
var app = express.createServer();
app.configure(function(){ //... });
require('./foo')(app);
// foo.js
exports = module.exports = function(app){
app.get('/whatever', function(req, res){});
};
The exploding app.js file prompted a couple of us to create a small reference app to codify a standard Express app structure. It's not rocket science, but rather a set of conventions that makes things more organized.
You can find it here: https://github.com/EAAppFoundry/tableau
We'd love suggestions/pull requests if there something we got wrong or is missing.
I don't think there should be any real problem with looping through the directory tree and generating the routes. However, it'll be hard to define route based middleware and other routing features (such as variables in the routes) in a nice way.
I wrote a library that I use to define my routes declaratively and with minimal repetition which you might be interested in. It's inspired by Rails resourceful routing and is pretty flexible - the idea is to build a hash of routes and subroutes; there are also facilities to define groups of routes, middleware and variables.
https://github.com/cheesun/express-declarative-routing
Although it doesn't automatically generate the routes based on your directory structure, I think that'd be a cool feature and welcome you add it to the library.

Browser history for Flash (or AJAX)

What is the best tool / practice to enable browser history for Flash (or AJAX) websites?
I guess the established practice is to set and read a hash-addition to the URL like
http://example.com/#id=1
I am aware of the Flex History Manager, but was wondering if there are any good alternatives to consider. Would also be interested in a general AJAX solution or best practice.
SWFAddress has been widely used and tested. It makes it almost trivial (given you plan ahead) to handle deeplinking in Flash. It provides a JS and AS library that work together and make the whole process pretty foolproof. You'd want to look at something like RSH for AJAX.
I've used swfadress for some small stuff.
For AJAX, something like Really Simple History is great.
This will seem a bit roundabout, but I'm currently using the dojo framework for that. There's a dojo.back that was very useful when my UI was mostly JS/HTML. Now that I've gone to flex for more power, fluid animations, and browser stability, the only thing I've need to keep using has been the back URL.
FlexBuilder seemed to have it's own browser history in default projects.
Also, the Flex 3 Cookbook has a recipe for using mx.managers.HistoryManager to create your own custom history management. I have plans to give this a try someday to remove our dependence on the dojo.back, but haven't had time yet.
I've rolled my own solutions that were ultra-simple like this:
(function() {
var oldHash, newHash;
function checkHash() {
// Grab the hash
newHash = document.location.hash;
// Check to see if it changed
if (oldHash != newHash) {
// Trigger a custom event if it changed,
// passing the old and new values as
// metadata on the event.
$(document).trigger('hash.changed', {
old: oldHash,
new: newHash
});
// Update the oldHash for the next check
oldHash = newHash;
}
}
// Poll the hash every 10 milliseconds.
// You might need to alter this time based
// on performance
window.setInterval(checkHash, 10);
})(jQuery);
Then you just need to have event handlers for the 'hash.changed' event to respond accordingly based on what the new value is. The approach works will in super simple cases.

Resources