在AngularJS嵌套状态嵌套视图 [英] Nested views with nested states in AngularJS

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

问题描述

我试图使嵌套状态,但什么是错的,我想不出为什么。

我有这些国家在我的角度应用程序:

  /客户(名单客户)
/客户/:ID(显示客户端)
/客户/新(新客户)

而现在,我试图做的事:

  /客户/:ID /任务(名单客户任务)
/客户/:ID /任务/新(创建此客户端新任务)
/客户/:ID /任务/:idTask(显示客户端的任务)

所有状态都在,但任务规定是不会改变的内容。

我的 index.html的的使用 UI视图主

 <节ID =容器>
    <报头GT;< /头>
    <&栏GT;< /侧边栏>
    <节类=主要内容 - 包装NG-CLASS ={'主':崩溃}>
        <节ID =主要内容>
            <格UI视图=主>< / DIV>
        < /节>
    < /节>
< /节>

我的 client.tpl.html 的与UI视图内容:

 < D​​IV CLASS =行>
    < D​​IV CLASS =COL-MD-12>
        < UL类=面包屑>
            <立GT;< A HREF UI的SREF =家>家庭和LT; / A>< /李>
            <李班=主动>客户与LT; /李>
        < / UL>
    < / DIV>
< / DIV>
<格UI视图=内容>< / DIV>

我的应用程序的状态:

  $ stateProvider
    .STATE('/',{
        网址:'/',
        templateUrl:/app/application/application.tpl.html',
        摘要:真
    })    // CLIENT
    .STATE('客户',{
        网址:'/客户端',
        摘要:真实,
        观点:{
            '主':{
                templateUrl:/app/client/client.tpl.html',
                控制器:'ClientController
            }
        }
    })
    .STATE('client.list',{
        网址:'/名单,
        观点:{
            内容:{
                templateUrl:/app/client/client.list.tpl.html',
                控制器:'ClientListController
            }
        }
    })
    .STATE('client.new',{
        网址:'/新,
        观点:{
            内容:{
                templateUrl:/app/client/client.new.tpl.html',
                控制器:'ClientNewController
            }
        }
    })
    .STATE('client.show',{
        网址:'/:身份证',
        观点:{
            内容:{
                templateUrl:/app/client/client.show.tpl.html',
                控制器:'ClientShowController',
            }
        }
    })

任务状态

  //任务
    .STATE('client.details',{
        网址:'/:idClient',
        摘要:真实,
        观点:{
            内容:{
                templateUrl:/app/task/task.tpl.html',
                控制器:'TaskController
            }
        }
    })
    .STATE('client.details.task',{
        网址:'/任务,
        观点:{
            内容:{
                templateUrl:/app/task/task.list.tpl.html',
                控制器:'TaskListController
            }
        }
    })
    .STATE('client.details.task.new',{
        网址:'/新,
        观点:{
            内容:{
                templateUrl:/app/task/task.new.tpl.html',
                控制器:'TaskNewController
            }
        }
    })
    .STATE('client.details.task.show',{
        网址:'/:idTask',
        观点:{
            内容:{
                templateUrl:/app/task/task.show.tpl.html',
                控制器:'TaskShowController
            }
        }
    });

所以,当我点击进入:

  /客户端
/客户/:ID
/客户/新

一切工作正常,内容的变化,但是,当我点击进入:

  /客户/:ID /任务
/客户/:ID /任务/:idTask
/客户/:ID /任务/新

内容不会改变,实际上,内容变得空洞。


更新1

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

指令:

  .directive('边栏',[功能(){
    返回{
        限制:'E',
        更换:真实,
        templateUrl:/common/partials/sidebar.html
    };
}])

模板:

 <一边类=侧边栏NG-CLASS ={'侧边栏切换:崩溃}NG控制器=SidebarController为侧边栏>
    < D​​IV ID =leftside导航级=纳米>
        < UL类=纳米含量>
            <李班=主动>
                < A HREF UI的SREF =家>< I类=发发的仪表板>< / I><跨度>首页< / SPAN>< / A>
            < /李>
            <李班=子菜单中的>
                < A HREF NG点击=切换()>
                    < I类=发发用户>< / I>
                    <跨度>客户与LT; / SPAN>
                    < I类=箭发发角右右拉式>< / I>
                &所述; / A>
                < UL风格=高度:{{高度}}像素;溢出:隐藏;>
                    <李NG重复=客户端session.clients>
                        &所述; A HREF UI-SREF =client.details.task({ID:client.id})> {{client.name}}&下; / A>
                    < /李>
                < / UL>
            < /李>
        < / UL>
    < / DIV>
< /一旁>

UI-SREF 的链接是: /客户端/ 10 /任务



解决方案

解决方案有惊人的简单,但背后的理念可能有点挑战性。

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

客户端根的状态是没有任何变化。它注入其观点,到用户界面视图=主根状态的(的index.html)

  // CLIENT
.STATE('客户',{
    ...
    观点:{
        '主':{
            templateUrl:/app/client/client.tpl.html',
            ...
        }
    }
})

现在,我们有第一级的孩子。他们将针对用户界面视图=内容他们的父母的(客户端和它的模板注入用户界面视图=主

  .STATE('client.list',{
    观点:{
        内容:{
    ....
})
.STATE('client.new',{
    网址:'/新,
    观点:{
        内容:{
    ...
})
...

所以到现在为止,一切工作。下面是一个变化。我们再试一次注入我们的模板到用户界面视图=内容 - 好。但它不是在我们的父定义。这是我们的祖父母 - 一个客户端状态。所以我们跳过一个级别。我们必须使用绝对命名为视图名称定位

  //任务
.STATE('client.details.task',{
    观点:{
        //错误
        内容:{
        //正确
        内容@客户:{
})
.STATE('client.details.task.new',{
    观点:{
        //错误
        内容:{
        //正确
        内容@客户:{
    }
})
...

现在应该很清楚。如果没有,也许这可以帮助一点。第一级的孩子,将与这个状态定义甚至工作

  .STATE('client.list',{
    观点:{
        //工作
        内容:{
        //还在努力
        内容@客户:{
    ....
})

因为我们只是用绝对的命名 - 当它为我们所做的开箱(语法糖)。欲了解更多,甚至更好的说明,请参阅文档:

视图名称 - 相对与绝对名称

小举:


  

在幕后,每一个观点被分配遵循的方案绝对名称 视图名@ Statename的 ,其中视图名是所使用的名称view指令和国家名称是国家的绝对名称,例如: contact.item。您也可以选择在绝对语法来写你的视图名称。


  
  

例如,在previous例如也可以写为:


  .STATE('报告',{
    观点:{
      过滤器@:{},
      资料表@:{},
      图@:{}
    }
})

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

I have these states in my angular app:

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

And now, I'm trying to do:

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

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

My index.html with the ui-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>

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>

My app states:

$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 states

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

So, when I click to go to:

/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.


UPDATE 1

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

Directive:

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

Template:

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

The link in ui-sref is: /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

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',
            ...
        }
    }
})

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': {
    ...
})
...

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': {         
    }
})
...

Now it should be clear. If not, maybe this could help a bit. The first level children, would work even with this state definition

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

Because we just used absolute naming - where the it is done for us out of the box (syntactic sugar). For more and even better explanation, please, see documentation:

View Names - Relative vs. Absolute Names

small cite:

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