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

Javascript AngularJS UI路由器命名视图延迟加载,javascript,angularjs,asp.net-mvc-4,angular-ui-router,Javascript,Angularjs,Asp.net Mvc 4,Angular Ui Router,AngularJS UI路由器命名视图加载基于用户访问,而不是在状态路由访问时加载 例子: 在上面的示例中,当用户访问状态main时,UI路由器从服务器加载所有命名视图html <tab ng-repeat="tab in tabs"> <div> <div ui-view='{{tab.view}}'></div> </div> </tab> 问题:

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

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

<tab ng-repeat="tab in tabs">    
    <div>     
        <div ui-view='{{tab.view}}'></div>
    </div>
 </tab>
问题: 我们可以在下面需要时加载命名视图吗?我的意思是,每当我们动态添加新标签,然后只从服务器加载受尊重的视图html

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


代码> 如果你想从模板URL中动态地加载你的Tab内容,根据在 $Simult.Tabs中定义的用户可用的标签的值,你应该考虑使用简单的指令而不是UI路由器视图。p> 正如您已经发现的,ui路由器将尝试加载子视图,而不管它们是否在该状态的主视图中被引用

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

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

.directive('template',['$compile','$http',function($compile,$http){
返回{
限制:“A”,
替换:false,
链接:函数($scope,element,attrs){
var-template=attrs['template'];
var控制器=属性['controller'];
如果(模板!==未定义){
//加载模板
$http.get(模板).success(函数(html){
//设置模板
var e=angular.element(controller==undefined | | | controller.length==0?html:“+html+”);
var compiled=$compile(e);
html(e);
汇编($范围);
});
}
}
};
}]);
因此,此代码使用
$http
服务从服务器获取模板。然后,它使用
$compile
服务将作用域应用于角度模板,并将其呈现到目标元素中

用法: 更新主选项卡模板的格式,如下所示。注意:我们不再引用
ui视图
,而是调用
模板
指令,传入我们要加载到
div中的
url
。以
div
的当前内容作为加载指示器

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

主页/shell中

完整资料来源: 这就是上面给出的代码,例如AngularJS应用程序。假设模板路径有效,即
home/shell
home/tab1


角度视图
angular.module('myTabbedApp',['ui.router'])
/*主页的控制器,即主页/外壳*/
.controller('MainPageTabController',['$scope',函数($scope){
//根据代码的要求动态设置页面选项卡
$scope.tabs={
'tab1':{template:'home/tab1'},
'tab2':{template:'home/tab2',controller:'Tab2Controller'},
'tab3':{template:'home/tab3'}
};
}])
/*选项卡2的控制器示例*/
.controller('Tab2Controller',['$scope',function$scope){
$scope.hello=“world”;
}])
/*ui路由器的状态提供程序*/
.config(['$stateProvider',函数($stateProvider){
$stateProvider
.state(“登录”,
{
url:“/login”,
templateUrl:“登录/索引”
})
.州(“主要”,
{
url:“/main”,
templateUrl:“主/外壳”,
控制器:“MainPageTabController”
});
}])
/*动态加载模板的指令*/
.directive('template',['$compile','$http',function($compile,$http){
返回{
限制:“A”,
替换:false,
链接:函数($scope,element,attrs){
var-template=attrs['template'];
如果(模板!==未定义){
//加载模板
$http.get(模板).success(函数(html){
//设置模板
var e=angular.element(html);
var compiled=$compile(e);
html(e);
汇编($范围);
});
}
}
};
}]);

我希望这有帮助。如果您对某些内容有疑问,请提问。

只是澄清一下,您所问的问题是否可以仅从服务器加载受尊重的视图而不加载所有内容?也许这会有所帮助:默认情况下,命名视图在状态路由后无法动态加载,指令对我们有效。出于好奇,此模板指令与@ShaunScovil有何区别?@ShaunScovil此指令允许您为视图动态指定控制器,据我所知,您无法为仅加载了
ng include
的模板指定控制器。或者,您可以在
ng include
的相同元素上使用
ng controller
。示例:@ShaunScovil没错,您可以在同一元素上使用
ng controller
,但是
<tab ng-repeat="(tabName,tab) in tabs">
    <div template='{{tab.template}}' controller="{{tab.controller}}">Loading {{tabName}} ...</div>
 </tab>
<!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>