apps/meteor/packages/flow-router/client/route.js
Route = function (router, pathDef, options, group) {
options = options || {};
this.options = options;
this.pathDef = pathDef;
// Route.path is deprecated and will be removed in 3.0
this.path = pathDef;
if (options.name) {
this.name = options.name;
}
this._action = options.action || Function.prototype;
this._subscriptions = options.subscriptions || Function.prototype;
this._triggersEnter = options.triggersEnter || [];
this._triggersExit = options.triggersExit || [];
this._subsMap = {};
this._router = router;
this._params = new ReactiveDict();
this._queryParams = new ReactiveDict();
this._routeCloseDep = new Tracker.Dependency();
// tracks the changes in the URL
this._pathChangeDep = new Tracker.Dependency();
this.group = group;
};
Route.prototype.clearSubscriptions = function () {
this._subsMap = {};
};
Route.prototype.register = function (name, sub, options) {
this._subsMap[name] = sub;
};
Route.prototype.getSubscription = function (name) {
return this._subsMap[name];
};
Route.prototype.getAllSubscriptions = function () {
return this._subsMap;
};
Route.prototype.callAction = function (current) {
var self = this;
self._action(current.params, current.queryParams);
};
Route.prototype.callSubscriptions = function (current) {
this.clearSubscriptions();
if (this.group) {
this.group.callSubscriptions(current);
}
this._subscriptions(current.params, current.queryParams);
};
Route.prototype.getRouteName = function () {
this._routeCloseDep.depend();
return this.name;
};
Route.prototype.getParam = function (key) {
this._routeCloseDep.depend();
return this._params.get(key);
};
Route.prototype.getQueryParam = function (key) {
this._routeCloseDep.depend();
return this._queryParams.get(key);
};
Route.prototype.watchPathChange = function () {
this._pathChangeDep.depend();
};
Route.prototype.registerRouteClose = function () {
this._params = new ReactiveDict();
this._queryParams = new ReactiveDict();
this._routeCloseDep.changed();
this._pathChangeDep.changed();
};
Route.prototype.registerRouteChange = function (currentContext, routeChanging) {
// register params
var params = currentContext.params;
this._updateReactiveDict(this._params, params);
// register query params
var queryParams = currentContext.queryParams;
this._updateReactiveDict(this._queryParams, queryParams);
// if the route is changing, we need to defer triggering path changing
// if we did this, old route's path watchers will detect this
// Real issue is, above watcher will get removed with the new route
// So, we don't need to trigger it now
// We are doing it on the route close event. So, if they exists they'll
// get notify that
if (!routeChanging) {
this._pathChangeDep.changed();
}
};
Route.prototype._updateReactiveDict = function (dict, newValues) {
var currentKeys = _.keys(newValues);
var oldKeys = _.keys(dict.keyDeps);
// set new values
// params is an array. So, _.each(params) does not works
// to iterate params
_.each(currentKeys, function (key) {
dict.set(key, newValues[key]);
});
// remove keys which does not exisits here
var removedKeys = _.difference(oldKeys, currentKeys);
_.each(removedKeys, function (key) {
dict.set(key, undefined);
});
};