ui-view不会渲染模板中的两个级别,无法从状态解析

时间:2015-04-13 18:41:27

标签: angularjs angular-ui-router

我一直在努力理解angular的ui-router。

我在这里要完成的是在一个ui-view中加载模板,该视图是2级。

包含登录和注册的主页面如下所示:

<body>
    <div ui-view="anonymous"></div>
    <div ui-view="home"></div>
</body>

anonymous ui-view内,我会相应地渲染我的登录和注册模板。

用户登录后,我会在frame.html home内呈现ui-view模板。

frame.html模板中,我们有一个信息中心的菜单系统,其中包含内部所有states的导航。

此外,frame.html包含名为ui-view的更深home_content,它会在其中呈现每个模板。

<div id="page-inner">
    <!--UI RENDER FOR DASHBOARD HOME INNER CONTENT -->
    <div ui-view="home_content"></div>
</div>

在上一个有关此问题的问题中,我能够使用它周围的框架(菜单)在home_content内呈现初始内容,但菜单中的链接继续产生:

Error: Could not resolve 'user.invoice' from state 'user.home'

这是我的完整app.js

var app = angular.module("Application", [
    'ui.router',
    'ngMessages',
    'ui-notification',
    'angularSpinner',
    'accountModule',
    'dashboardModule'


]);

app.constant("AccessLevels", {
    anon: 0,
    user: 1
});

app.config(["$stateProvider", "$urlRouterProvider", "AccessLevels", function ($stateProvider, $urlRouterProvider, AccessLevels) {

    /* ANONYMOUSE USERS */
    $stateProvider
        .state('anon', {
            abstract: true,
            template: '<ui-view/>',
            data: {
                access: AccessLevels.anon
            }
        })
        .state('anon.login', {
            url: '/login',
            views: { 
                'anonymous@': {
                    templateUrl: 'Client/scripts/app/partials/account/login.html',
                    controller: 'loginCtrl'
                }
            }
        })
        .state('anon.register', {
            url: '/register',
            views: {
                'anonymous@': {
                    templateUrl: 'Client/scripts/app/partials/account/registration.html',
                    controller: 'registerCtrl'
                }
            }
        });

    /* AUTHENTICATED USERS */
    $stateProvider
        .state('user', {
            abstract: true,
            data: {
                access: AccessLevels.user
            },
            views: {
                'home': {
                    template: '<div ui-view="home"></div>',
                }
            }
        })
        .state('user.home', {
            url: '/home',
            views: {
                'home@': {
                    templateUrl: 'Client/scripts/app/partials/home/frame.html'
                },
                'home_content@user.home': {
                    templateUrl: 'Client/scripts/app/partials/home/dashboard/index.html',
                    controller: 'dashboardCtrl'
                },
                'home_content@user.delivery': {
                    templateUrl: 'Client/scripts/app/partials/home/deliveries/deliveries.html',
                    controller: 'deliveryCtrl'
                },
                'home_content@user.invoice': {
                    templateUrl: 'Client/scripts/app/partials/home/invoices/invoices.html',
                    controller: 'invoiceCtrl'
                },
                'home_content@user.order': {
                    templateUrl: 'Client/scripts/app/partials/home/orders/orders.html',
                    controller: 'orderCtrl'
                }
            }
        });

    $urlRouterProvider.otherwise('/home');
}]);

app.run(function ($rootScope, $state, Auth) {

    $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
        if (!Auth.authorize(toState.data.access)) {
            event.preventDefault();
            $state.go('anon.login');
        }
    });
});

在我的frame.html我有菜单系统,这是其中一个链接:

<a class="active-menu" ui-sref="user.home">Home</a>

我是否正确设置了这个?如何在最内层的ui-view内呈现这些模板?

1 个答案:

答案 0 :(得分:2)

此处的问题与

的不匹配有关
  1. 定义了视图目标(ui-view)和
  2. 针对他们的观看次数
  3. 我们可以读到:

      

    ...另外,frame.html拥有更深层ui-view名为 'home_content' 的内容,它会在其中呈现每个模板......

    所以,只有一个目标。一个名为 'home_content'

    的目标

    但在状态views : {},我们可以看到许多观点......试图达到同一目标:

    .state('user.home', {
        url: '/home',
        views: {
            'home@': {
                templateUrl: 'Client/scripts/app/partials/home/frame.html'
            },
            'home_content@user.home': {
                ....
            },
            'home_content@user.delivery': {
                ....
            }
            'home_content@user.invoice': {
                ....
             }
            ...
    

    我们现在可以看到,我们定位一个名称视图&#39; home_content&#39; 。它不会起作用,除非它存在于层次结构中(父级有home_content,祖父有home_content)。那就像

    .state('grandParent.parent.current', {
        views: {
            '' : { template: '<div ui-view="home_content"></div>' },
            ...
            // I. here we target current state
            'home_content@grandparent.parent.current': {
                ....
            },
    
            // II. here we target our parent, which would be the same
            'home_content@grandparent.parent': {
            // as we use relative names
            'home_content': {
                ....
            }
    
            // III. here we target grandParent
            'home_content@grandparent': {
                ....
             }
            ...
    

    所以,这就是绝对命名的工作原理:

    View Names - Relative vs. Absolute Names

      

    在幕后,为每个视图分配一个绝对名称,该名称遵循viewname @ statename的方案,其中viewname是视图指令中使用的名称,状态名称是状态的绝对名称,例如, contact.item。您还可以选择以绝对语法编写视图名称。

    在我们的场景中有什么用?好吧,我们必须在 frame.html

    中使用更多目标
    <div ui-view="home_content"></div>
    <div ui-view="other1"></div>
    <div ui-view="other2"></div>
    <div ui-view="other3"></div>
    

    然后我们可以针对他们:

    .state('user.home', {
        url: '/home',
        views: {
            'home@': {
                templateUrl: 'Client/scripts/app/partials/home/frame.html'
            },
            'home_content@user.home': {
                ....
            },
            'other1@user.home': {
                ....
            }
            'other2@user.home': {
            ...
    

    如果仍然不那么清楚,我建议观察这段巨大的代码: