ui-视图不会在两层中呈现模板,无法从状态解析

ui-view won't render template two levels in, Could not resolve from state

我一直在努力理解 angular 的 ui-路由器。

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

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

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

anonymous ui-view 中,我相应地呈现我的登录和注册模板。

用户登录后,我在 home ui-view.

中呈现 frame.html 模板

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. 定义的视图目标(ui-view)和
  2. 针对他们的观看次数

我们可以读到:

... Also, frame.html holds the deeper ui-view called 'home_content' which will render each template within it...

所以,只有一个目标。一个名为 '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': {
            ....
         }
        ...

正如我们现在所见,我们定位了一个名称视图 'home_content'。它不会工作,除非它存在于层次结构中(父级有 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

Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname@statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.

在我们的场景中什么会起作用?好吧,我们必须在 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': {
        ...

如果还不是很清楚,我会建议观察这段巨大的代码: