Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

feat(1.x): support routing to a directive #228

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion dist/grammar.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions dist/pipeline.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

133 changes: 123 additions & 10 deletions dist/router.es5.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ angular.module('ngNewRouter', [])
.factory('$setupRoutersStep', setupRoutersStepFactory)
.factory('$initLocalsStep', initLocalsStepFactory)
.factory('$initControllersStep', initControllersStepFactory)
.factory('$bindRouteParamsForDirectiveStep', bindRouteParamsForDirectiveStepFactory)
.factory('$runCanDeactivateHookStep', runCanDeactivateHookStepFactory)
.factory('$runCanActivateHookStep', runCanActivateHookStepFactory)
.factory('$loadTemplatesStep', loadTemplatesStepFactory)
Expand All @@ -29,7 +30,9 @@ angular.module('ngNewRouter', [])
*/
angular.module('ng')
.provider('$controllerIntrospector', $controllerIntrospectorProvider)
.config(controllerProviderDecorator);
.provider('$compileIntrospector', $compileIntrospectorProvider)
.config(controllerProviderDecorator)
.config(compileProviderDecorator);

/*
* decorates with routing info
Expand All @@ -43,6 +46,15 @@ function controllerProviderDecorator($controllerProvider, $controllerIntrospecto
}
controllerProviderDecorator.$inject = ["$controllerProvider", "$controllerIntrospectorProvider"];

function compileProviderDecorator($compileProvider, $compileIntrospectorProvider) {
var directive = $compileProvider.directive;
$compileProvider.directive = function (name, directiveFactory) {
$compileIntrospectorProvider.directive(name, directiveFactory);
return directive.apply(this, arguments);
};
}
compileProviderDecorator.$inject = ["$compileProvider", "$compileIntrospectorProvider"];

/*
* private service that holds route mappings for each controller
*/
Expand Down Expand Up @@ -77,12 +89,50 @@ function $controllerIntrospectorProvider() {
}
}

function routerFactory($$rootRouter, $rootScope, $location, $$grammar, $controllerIntrospector) {

/*
* private service that holds route mappings for each controller
*/
function $compileIntrospectorProvider() {
var directiveFactories = [];
var onDirectiveDefined = null;
return {
directive: function (name, directiveFactory) {
if (angular.isArray(directiveFactory)) {
directiveFactory = directiveFactory[directiveFactory.length - 1];
}
if (directiveFactory.$routeConfig) {
if (onDirectiveDefined) {
onDirectiveDefined(name, directiveFactory.$routeConfig);
} else {
directiveFactories.push({name: name, config: directiveFactory.$routeConfig});
}
}
},
$get: ['$componentLoader', '$injector', function ($componentLoader, $injector) {
return function (newOnDirectiveDefined) {
onDirectiveDefined = function (name, config) {
return newOnDirectiveDefined(name, config);
};
while(directiveFactories.length > 0) {
var rule = directiveFactories.pop();
onDirectiveDefined(rule.name, rule.config);
}
}
}]
}
}

function routerFactory($$rootRouter, $rootScope, $location, $$grammar, $controllerIntrospector, $compileIntrospector) {

$controllerIntrospector(function (name, config) {
$$grammar.config(name, config);
});

$compileIntrospector(function (name, config) {
$$grammar.config(name, config);
});

$rootScope.$watch(function () {
return $location.path();
}, function (newUrl) {
Expand All @@ -100,7 +150,7 @@ function routerFactory($$rootRouter, $rootScope, $location, $$grammar, $controll

return $$rootRouter;
}
routerFactory.$inject = ["$$rootRouter", "$rootScope", "$location", "$$grammar", "$controllerIntrospector"];
routerFactory.$inject = ["$$rootRouter", "$rootScope", "$location", "$$grammar", "$controllerIntrospector", "$compileIntrospector"];

/**
* @name ngViewport
Expand Down Expand Up @@ -189,7 +239,11 @@ function ngViewportDirective($animate, $injector, $q, $router) {
});

var newController = instruction.controller;
newScope[componentName] = newController;
if (instruction.directive && instruction.directive.controllerAs) {
newScope[instruction.directive.controllerAs] = newController;
} else {
newScope[componentName] = newController;
}

var result;
if (currentController && currentController.deactivate) {
Expand Down Expand Up @@ -372,23 +426,56 @@ function initLocalsStepFactory() {
/*
* $initControllersStep
*/
function initControllersStepFactory($controller, $componentLoader) {
function initControllersStepFactory($controller, $componentLoader, $injector) {
return function initControllers(instruction) {
return instruction.router.traverseInstruction(instruction, function(instruction) {
var controllerName = $componentLoader.controllerName(instruction.component);
var directiveName = $componentLoader.directiveName(instruction.component);
var locals = instruction.locals;
var ctrl;
try {
ctrl = $controller(controllerName, locals);
} catch(e) {
console.warn && console.warn('Could not instantiate controller', controllerName);
ctrl = $controller(angular.noop, locals);
try {
var directives = $injector.get(directiveName);
// can't handle two names on the same directive yet
instruction.directive = directives[0];
ctrl = $controller(instruction.directive.controller, locals);
} catch(e) {
console.warn && console.warn('Could not instantiate controller', controllerName);
ctrl = $controller(angular.noop, locals);
}
}
return instruction.controller = ctrl;
});
}
}
initControllersStepFactory.$inject = ["$controller", "$componentLoader"];
initControllersStepFactory.$inject = ["$controller", "$componentLoader", "$injector"];

function bindRouteParamsForDirectiveStepFactory() {
return function bindRouteParamsForDirective(instruction) {
return instruction.router.traverseInstruction(instruction, function(instruction) {
if (instruction.directive && instruction.directive.bindToController) {
var bindings;
if (typeof instruction.directive.bindToController == 'object') {
// ng 1.4 object syntax
bindings = instruction.directive.$$bindings.bindToController;
} else if (instruction.directive.bindToController == true) {
// ng 1.3 syntax
bindings = instruction.directive.$$isolateBindings;
}
if (bindings) {
Object.keys(bindings).forEach(function(key) {
if (instruction.params[bindings[key].attrName]) {
instruction.controller[key] = instruction.params[bindings[key].attrName];
}
});
}
}
return true;
});
};
}

function runCanDeactivateHookStepFactory() {
return function runCanDeactivateHook(instruction) {
Expand Down Expand Up @@ -416,7 +503,16 @@ runCanActivateHookStepFactory.$inject = ["$injector"];
function loadTemplatesStepFactory($componentLoader, $templateRequest) {
return function loadTemplates(instruction) {
return instruction.router.traverseInstruction(instruction, function(instruction) {
var componentTemplateUrl = $componentLoader.template(instruction.component);
var componentTemplateUrl;
if (instruction.directive) {
if (instruction.directive.template) {
return instruction.template = instruction.directive.template
} else {
componentTemplateUrl = instruction.directive.templateUrl;
}
} else {
componentTemplateUrl = $componentLoader.template(instruction.component);
}
return $templateRequest(componentTemplateUrl).then(function (templateHtml) {
return instruction.template = templateHtml;
});
Expand All @@ -438,6 +534,7 @@ function pipelineProvider() {
'$setupRoutersStep',
'$initLocalsStep',
'$initControllersStep',
'$bindRouteParamsForDirectiveStep',
'$runCanDeactivateHookStep',
'$runCanActivateHookStep',
'$loadTemplatesStep',
Expand Down Expand Up @@ -493,6 +590,7 @@ function pipelineProvider() {
function $componentLoaderProvider() {

var DEFAULT_SUFFIX = 'Controller';
var DEFAULT_DIRECTIVE_SUFFIX = 'Directive';

var componentToCtrl = function componentToCtrlDefault(name) {
return name[0].toUpperCase() + name.substr(1) + DEFAULT_SUFFIX;
Expand All @@ -507,12 +605,22 @@ function $componentLoaderProvider() {
return name[0].toLowerCase() + name.substr(1, name.length - DEFAULT_SUFFIX.length - 1);
};

var componentToDirective = function componentToDirectiveDefault(name) {
return name + DEFAULT_DIRECTIVE_SUFFIX;
};

var directiveToComponent = function directiveToComponent(name) {
return name.substr(0, name.length - DEFAULT_DIRECTIVE_SUFFIX.length);
};

return {
$get: function () {
return {
controllerName: componentToCtrl,
template: componentToTemplate,
component: ctrlToComponent
component: ctrlToComponent,
directiveName: componentToDirective,
directiveToComponent: directiveToComponent
};
},

Expand Down Expand Up @@ -541,6 +649,11 @@ function $componentLoaderProvider() {
setTemplateMapping: function(newFn) {
componentToTemplate = newFn;
return this;
},

setDirectiveMapping: function(newFn) {
componentToDirective = newFn;
return this;
}
};
}
Expand Down
2 changes: 1 addition & 1 deletion dist/router.es5.min.js

Large diffs are not rendered by default.

14 changes: 11 additions & 3 deletions dist/router.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading