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

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

问题描述

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

示例:

$stateProvider.state(登录",{网址:/登录",templateUrl: getTemplateUrl(登录/索引")}).state(主要",{网址:/主",意见:{'': { templateUrl: getTemplateUrl('home/shell') },'test1@main': { templateUrl: 'home/test1' },'test2@main': { templateUrl: 'home/test2' },'test3@main': { templateUrl: getTemplateUrl('home/test3') }}});

在上面的例子中,当用户访问状态 main 时,UI-router 从服务器加载所有命名视图 html.

问题:

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

<div><div ui-view='{{tab.view}}'></div>

</tab>

解决方案

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

因为您已经发现 ui-router 将尝试加载子视图,而不管它们是否在该状态的主视图中被引用.

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

template 指令:

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

.directive('template', ['$compile', '$http', function($compile, $http) {返回 {限制:'A',替换:假,链接:函数($scope,元素,属性){var template = attrs['template'];var controller = attrs['controller'];如果(模板!==未定义){//加载模板$http.get(template).success(function(html){//设置模板var e = angular.element(controller === undefined || controller.length === 0 ? html : "<span ng-controller='" + controller + "'>" + html + "</span>");var 编译 = $compile(e);element.html(e);编译($范围);});}}};}]);

所以这段代码使用 $http 服务从服务器获取模板.然后它使用 $compile 服务将范围应用到 angular 模板,并将其渲染到目标元素中.

用法:

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

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

home/shell中:

<div template='{{tab.template}}' controller="{{tab.controller}}">正在加载 {{tabName}} ...</div></tab>

然后设置要显示的标签:

$scope.tabs = {'tab1': { 模板: 'home/tab1'},'tab2': { 模板: 'home/tab2', 控制器: 'Tab2Controller' },'tab3': { 模板: 'home/tab3'}};

<小时>

完整来源:

这只是把上面给出的代码,作为一个 AngularJS 应用程序的例子.假设模板路径有效,即 home/shellhome/tab1

<头><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>角度视图</title><body ng-app="myTabbedApp"><div ui-view></div><脚本>angular.module('myTabbedApp', ['ui.router'])/* 主页面的控制器,即.家/外壳*/.controller('MainPageTabController', ['$scope', function($scope) {//根据代码的需要动态设置页面选项卡$scope.tabs = {'tab1': { 模板: 'home/tab1'},'tab2': { 模板: 'home/tab2', 控制器: 'Tab2Controller' },'tab3': { 模板: 'home/tab3'}};}])/* 选项卡 2 的示例控制器 */.controller('Tab2Controller', ['$scope', function($scope) {$scope.hello = "世界";}])/* ui 路由器的状态提供程序 */.config(['$stateProvider', function($stateProvider){$stateProvider.state("登录",{网址:/登录",模板网址:登录/索引"}).state("主要",{网址:/主",templateUrl: 'home/shell',控制器:'MainPageTabController'});}])/* 动态加载模板的指令 */.directive('template', ['$compile', '$http', function($compile, $http) {返回 {限制:'A',替换:假,链接:函数($scope,元素,属性){var template = attrs['template'];如果(模板!==未定义){//加载模板$http.get(template).success(function(html){//设置模板var e = angular.element(html);var 编译 = $compile(e);element.html(e);编译($范围);});}}};}]);</html>

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

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

Example:

$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') }                     
    }
});

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

Question:

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>

解决方案

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.

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 Directive:

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);
                });
            }
        }
    };
}]);

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.

Usage:

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.

(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.)

in home/shell:

<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'}
};


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天全站免登陆