AngularJS中具有嵌套状态的嵌套视图 [英] Nested views with nested states in AngularJS

查看:30
本文介绍了AngularJS中具有嵌套状态的嵌套视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建嵌套状态,但出了点问题,我不知道为什么.

I'm trying to make nested states, but something is wrong and I can't figure out why.

我的 Angular 应用中有这些状态:

I have these states in my angular app:

/client (list clients)
/client/:id (show client)
/client/new (new client)

现在,我正在尝试做:

/client/:id/task (list clients tasks)
/client/:id/task/new (create new task for this client)
/client/:id/task/:idTask (show the client task)

所有状态都在工作,但 task 状态并没有改变内容.

All the states are working, but the task states is not changing the content.

我的 index.htmlui-view "main":

<section id="container">
    <header></header>
    <sidebar></sidebar>
    <section class="main-content-wrapper" ng-class="{'main':collapse}">
        <section id="main-content">
            <div ui-view="main"></div>
        </section>
    </section>
</section>

我的 client.tpl.html 带有 ui-view 内容":

My client.tpl.html with the ui-view "content":

<div class="row">
    <div class="col-md-12">
        <ul class="breadcrumb">
            <li><a href ui-sref="home">Home</a></li>
            <li class="active">Clients</li>
        </ul>
    </div>
</div>
<div ui-view="content"></div>

我的应用状态:

$stateProvider
    .state('/', {
        url: '/',
        templateUrl: '/app/application/application.tpl.html',
        abstract: true
    })

    // CLIENT
    .state('client', {
        url: '/client',
        abstract: true,
        views: {
            'main': {
                templateUrl: '/app/client/client.tpl.html',
                controller: 'ClientController'
            }
        }
    })
    .state('client.list', {
        url: '/list',
        views: {
            'content': {
                templateUrl: '/app/client/client.list.tpl.html',
                controller: 'ClientListController'
            }
        }
    })
    .state('client.new', {
        url: '/new',
        views: {
            'content': {
                templateUrl: '/app/client/client.new.tpl.html',
                controller: 'ClientNewController'
            }
        }
    })
    .state('client.show', {
        url: '/:id',
        views: {
            'content': {
                templateUrl: '/app/client/client.show.tpl.html',
                controller: 'ClientShowController',
            }
        }
    })

任务状态

    // TASKS
    .state('client.details', {
        url: '/:idClient',
        abstract: true,
        views: {
            'content': {
                templateUrl: '/app/task/task.tpl.html',
                controller: 'TaskController'
            }
        }
    })
    .state('client.details.task', {
        url: '/task',
        views: {
            'content': {
                templateUrl: '/app/task/task.list.tpl.html',
                controller: 'TaskListController'
            }
        }
    })
    .state('client.details.task.new', {
        url: '/new',
        views: {
            'content': {
                templateUrl: '/app/task/task.new.tpl.html',
                controller: 'TaskNewController'
            }
        }
    })
    .state('client.details.task.show', {
        url: '/:idTask',
        views: {
            'content': {
                templateUrl: '/app/task/task.show.tpl.html',
                controller: 'TaskShowController'
            }
        }
    });

所以,当我点击转到:

/client
/client/:id
/client/new

一切正常,内容发生变化,但是,当我点击转到:

Everything works fine, the content change, but, when I click to go to:

/client/:id/task
/client/:id/task/:idTask
/client/:id/task/new

内容不变,实际上内容变空了.

The content don't change, actually, the content gets empty.

更新 1

任务列表的链接在我的侧边栏,侧边栏是指令:

The link to the task list is in my sidebar, sidebar is a directive:

指令:

.directive('sidebar', [function () {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: '/common/partials/sidebar.html'
    };
}])

模板:

<aside class="sidebar" ng-class="{'sidebar-toggle':collapse}" ng-controller="SidebarController as sidebar">
    <div id="leftside-navigation" class="nano">
        <ul class="nano-content">
            <li class="active">
                <a href ui-sref="home"><i class="fa fa-dashboard"></i><span>Home</span></a>
            </li>
            <li class="sub-menu">
                <a href ng-click="toggle()">
                    <i class="fa fa-users"></i>
                    <span>Clients</span>
                    <i class="arrow fa fa-angle-right pull-right"></i>
                </a>
                <ul style="height: {{height}}px; overflow: hidden;">
                    <li ng-repeat="client in session.clients">
                        <a href ui-sref="client.details.task({id:client.id})">{{client.name}}</a>
                    </li>
                </ul>
            </li>
        </ul>
    </div>
</aside>

ui-sref中的链接是:/client/10/task

推荐答案

解决方案非常简单,但背后的概念可能有点挑战性.

Solution there is surprisingly simple, but the concept behind could be a bit challenging.

所以状态定义应该是这样的

So the state definition should be like this

客户端根状态没有任何变化.它确实将其视图注入到根状态的 ui-view=main" (index.html)

Client root state is without any change. It does inject its view into ui-view="main" of the root state (index.html)

// CLIENT
.state('client', {
    ...
    views: {
        'main': {
            templateUrl: '/app/client/client.tpl.html',
            ...
        }
    }
})

现在,我们有了第一级的孩子.他们将针对其父 ui-view=content"(客户端及其模板注入 ui-view=main")

Now, we have first level children. They will target ui-view="content" of their parent (client and its template injected into ui-view="main")

.state('client.list', {
    views: {
        'content': {
    ....
})
.state('client.new', {
    url: '/new',
    views: {
        'content': {
    ...
})
...

所以到目前为止,一切正常.下面是一个变化.我们再次尝试将我们的模板注入 ui-view=content" - 很好.但它没有在我们的父级中定义.它处于我们的 grand-parent - Client 状态.所以我们跳过了一个级别.我们必须使用绝对命名来定位视图名称

So until now, everything is working. Below is a change. We try again inject our templates into ui-view="content" - good. But it is not defined in our parent. It is in our grand-parent - a Client state. So we are skipping one level. We have to use absolute naming for view name targeting

// TASKS
.state('client.details.task', {
    views: {
        // wrong
        'content': {
        // correct
        'content@client': {         
})
.state('client.details.task.new', {
    views: {
        // wrong
        'content': {
        // correct
        'content@client': {         
    }
})
...

现在应该很清楚了.如果没有,也许这会有所帮助.即使使用此状态定义,第一级子级也可以工作

.state('client.list', {
    views: {
        // working
        'content': {
        // also working
        'content@client': {
    ....
})

因为我们只使用了绝对命名——它是为我们开箱即用的(语法糖).如需更多更好的解释,请参阅文档:

小引用:

在幕后,每个视图都被分配了一个遵循 viewname@statename 方案的绝对名称,其中 viewname 是视图指令中使用的名称和状态名称是状态的绝对名称,例如联系方式.项目.您还可以选择以绝对语法编写视图名称.

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.

例如,前面的例子也可以写成:

For example, the previous example could also be written as:

.state('report',{
    views: {
      'filters@': { },
      'tabledata@': { },
      'graph@': { }
    }
})

这篇关于AngularJS中具有嵌套状态的嵌套视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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