基本上,我需要的是ngView
的替代方法,它允许我在html元素中加载自定义路由。
例如,这条路线:
$routeProvider.when('/some/path', {
templateUrl: 'some/template.html',
controller: someController,
controllerAs: 'ctrlAlias'
});
使用此指令(使用myRoute='/some/path'
):
<div routeView="myRoute" />
导致:
<div ng-controller="someController as ctrlAlias" ng-include src="some/template.html" />
由于兼容性和传统限制,我无法使用ui-router。 如何使用指令(或其他方式)实现此目的?
答案 0 :(得分:0)
所以,我调整了ngView中的代码来完成我需要的工作。 它不是很优雅,因为角度路由器模块有很多代码重复,但它工作得很好。 请注意,这仅适用于具有templateUrl的路由和不带参数的路由。
用法:
<div route-view="'/my/route'"></div>
<div route-view="myRoute"></div>
代码:
angular.module('app', [])
.directive('routeView', routeViewDirective)
.directive('routeView', routeViewFillContentDirective)
function routeViewDirective($animate, $parse, $q, $route, $sce, $templateRequest) {
return {
restrict: 'EA',
terminal: true,
priority: 400,
transclude: 'element',
link: routeViewDirectiveLink
};
function routeViewDirectiveLink(scope, $element, attributes, ctrl, $transclude) {
var model = $parse(attributes.routeView);
var currentScope;
var currentElement;
scope.$watch(model, update);
function cleanupLastView() {
if (currentScope) {
currentScope.$destroy();
currentScope = null;
}
if (currentElement) {
$animate.leave(currentElement);
currentElement = null;
}
}
function update(path) {
var route = $route.routes[path];
if (route && route.templateUrl) {
var newScope = scope.$new();
var clone = $transclude(newScope, function(clone) {
$animate.enter(clone, null, currentElement || $element);
cleanupLastView();
});
currentElement = clone;
currentScope = newScope;
} else {
cleanupLastView();
}
}
}
}
function routeViewFillContentDirective($compile, $controller, $parse, $q, $route, $sce, $templateRequest) {
return {
restrict: 'EA',
priority: -400,
link: routeViewFillContentDirectiveLink
};
function routeViewFillContentDirectiveLink(scope, $element, attributes) {
var path = $parse(attributes.routeView)(scope);
var route = $route.routes[path];
var templateUrl = route && $sce.getTrustedResourceUrl(route.templateUrl);
if (angular.isDefined(templateUrl)) {
$templateRequest(templateUrl).then(function(template) {
$element.html(template);
var link = $compile($element.contents());
if (route.controller) {
var controller = $controller(route.controller, { $scope: scope });
if (route.controllerAs) {
scope[route.controllerAs] = controller;
}
$element.data('$ngControllerController', controller);
$element.children().data('$ngControllerController', controller);
}
link(scope);
});
}
}
}