AngularJS UI路由器命名视图延迟加载 [英] AngularJS UI router named views lazy loading

查看:47
本文介绍了AngularJS UI路由器命名视图延迟加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

名为View的AngularJS UI路由器基于用户访问而不是在状态路由访问时加载视图.

AngularJS UI router named views loading based on user access rather than loading at the time of state route access.

$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.

In the above example, when a user accesses the state main the UI-router loads all the named views html from server.

我们可以在以下要求时加载命名视图吗?我的意思是,每当我们动态添加新标签时,便只会从服务器加载受尊重的视图html.

Can we load named-views when required below? I mean whenever we add new tab dynamically then only loading respected view html from server.

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

推荐答案

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

If you are looking to load your tab content dynamically from template urls based on the value of tabs available to the user as defined in $scope.tabs, you should consider using a simple directive rather than ui-router views.

您已经发现ui-router将尝试加载子视图,无论是否在该状态的主视图中引用了子视图.

As you have already discovered ui-router will try and load the subviews regardless of whether they are referenced in the main view for that state.

但是,我们可以使用自己的指令来加载模板,因此,由于该指令仅在主视图中存在时才运行,因此模板可以按需加载.

We can however use our own directive to load templates, and therefore because the directive only runs when present in the main view, the templates load on demand.

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

We create a template directive, that allows us to pull in a template into an html element.

.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服务将范围应用于角度模板,并将其渲染到目标元素中.

So this code uses the $http service to get the template from the server. Then it uses the $compile service to apply the scope to the angular template, and renders it into the target element.

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

Update the format of your main tabs template as below. Note we no longer reference ui-view, instead we call our template directive passing in the url we want to load in the div. With the current content of the div being the loading indicator.

(如果设置了controller属性,则模板将被具有ng-controller属性的<span>包装,因此可以应用模板控制器.这是可选的.)

(If the controller attribute is set the template will be wrapped with an <span> having the ng-controller attribute, so a template controller can be applied. This is optional.)

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

然后设置要显示的标签:

Then set the tabs you want to display:

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


完整来源:

这只是将上面给出的代码作为AngularJS应用的示例. 假设模板路径有效,即home/shellhome/tab1等.


Full source:

This just puts the code given above, as an example AngularJS app. Assumes the template paths are valid i.e. home/shell, home/tab1 etc.

<!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>

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

I hope this helps. If you have questions about something just ask.

这篇关于AngularJS UI路由器命名视图延迟加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆