AngularJS UI路由器命名视图延迟加载

时间:2015-05-07 21:03:35

标签: javascript angularjs asp.net-mvc-4 angular-ui-router

AngularJS UI路由器命名视图基于用户访问加载而不是在状态路由访问时加载。

实施例

$stateProvider
.state("login",
{
    url: "/login",
    templateUrl: getTemplateUrl("login/Index")
})    
.state("main",
{
    url: "/main",
    views: 
    {
        '': { templateUrl: getTemplateUrl('home/shell') },
        'test1@main': { templateUrl: 'home/test1' },
        'test2@main': { templateUrl: 'home/test2' },
        'test3@main': { templateUrl:  getTemplateUrl('home/test3') }                     
    }
});

在上面的示例中,当用户访问状态main时,UI路由器从服务器加载所有命名视图html。

问题:

我们可以在下方需要时加载命名视图吗?我的意思是每当我们动态添加新标签然后只从服务器加载受尊重的视图html。

<tab ng-repeat="tab in tabs">    
    <div>     
        <div ui-view='{{tab.view}}'></div>
    </div>
 </tab>

1 个答案:

答案 0 :(得分:5)

如果您希望根据$scope.tabs中定义的用户可用选项卡的值从模板URL动态加载选项卡内容,则应考虑使用简单指令而不是ui-router视图。

正如您已经发现ui-router将尝试加载子视图,无论它们是否在该状态的主视图中被引用。

然而,我们可以使用我们自己的指令来加载模板,因为该指令仅在主视图中存在时运行,模板按需加载。

template指令:

我们创建了一个template指令,允许我们将模板拉入html元素。

.directive('template', ['$compile', '$http', function($compile, $http) {
    return {
        restrict: 'A',
        replace: false,
        link: function($scope, element, attrs) {
            var template = attrs['template'];
            var controller = attrs['controller'];
            if(template!==undefined){
                // Load the template
                $http.get(template).success(function(html){
                    // Set the template
                    var e = angular.element(controller === undefined || controller.length === 0 ? html : "<span ng-controller='" + controller + "'>" + html + "</span>");
                    var compiled = $compile(e);
                    element.html(e);
                    compiled($scope);
                });
            }
        }
    };
}]);

因此,此代码使用$http服务从服务器获取模板。然后,它使用$compile服务将范围应用于角度模板,并将其呈现到目标元素中。

用法:

更新主要标签模板的格式,如下所示。请注意,我们不再引用ui-view,而是将template指令调用url传递给div,我们要加载div当前controller的内容是加载指标。

(如果设置了<span>属性,模板将使用ng-controller属性home/shell包装,因此可以应用模板控制器。这是可选的。 )

<tab ng-repeat="(tabName,tab) in tabs"> <div template='{{tab.template}}' controller="{{tab.controller}}">Loading {{tabName}} ...</div> </tab> 中的

$scope.tabs = {
    'tab1': { template: 'home/tab1'},
    'tab2': { template: 'home/tab2', controller: 'Tab2Controller' },
    'tab3': { template: 'home/tab3'}
};

然后设置要显示的标签:

home/shell

完整来源:

这只是将上面给出的代码作为示例AngularJS应用程序。 假设模板路径有效,即home/tab1<!DOCTYPE html> <html> <head> <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script> <meta charset="utf-8"> <title>Angular Views</title> </head> <body ng-app="myTabbedApp"> <div ui-view></div> <script> angular.module('myTabbedApp', ['ui.router']) /* Controller for the Main page ie. home/shell */ .controller('MainPageTabController', ['$scope', function($scope) { // Set the page tabs dynamically as required by your code $scope.tabs = { 'tab1': { template: 'home/tab1'}, 'tab2': { template: 'home/tab2', controller: 'Tab2Controller' }, 'tab3': { template: 'home/tab3'} }; }]) /* Example controller for Tab 2 */ .controller('Tab2Controller', ['$scope', function($scope) { $scope.hello = "world"; }]) /* State provider for ui router */ .config(['$stateProvider', function($stateProvider){ $stateProvider .state("login", { url: "/login", templateUrl: "login/index" }) .state("main", { url: "/main", templateUrl: 'home/shell', controller: 'MainPageTabController' }); }]) /* Directive to load templates dynamically */ .directive('template', ['$compile', '$http', function($compile, $http) { return { restrict: 'A', replace: false, link: function($scope, element, attrs) { var template = attrs['template']; if(template!==undefined){ // Load the template $http.get(template).success(function(html){ // Set the template var e = angular.element(html); var compiled = $compile(e); element.html(e); compiled($scope); }); } } }; }]); </script> </body> </html> 等。

3, 5, 7, 9, ... 303, 305

我希望这会有所帮助。如果您对某事有疑问,请询问。