AngularJS:如何使用UI路由器实现默认嵌套状态?

时间:2021-10-24 11:43:34

I currently have a root index.html with a single ui-view which gets replaced depending on which "page" the user is on, e.g. Books, Games etc. Taking the Books page as an example, this view has content that I'd like to display on all pages which are part of the "Books" space, but the central content will differ depending on if the user is on the Books "homepage" or looking at a specific book. To facilitate this, my books.html has a nested state which either includes books_list.html or books_detail.html.

我目前有一个带有单个ui-view的root index.html,它取决于用户所在的“页面”,例如书籍,游戏等。以书籍页面为例,此视图包含我想要在“书籍”空间的所有页面上显示的内容,但中心内容将根据用户是否开启而有所不同书籍“主页”或看一本特定的书。为方便起见,我的books.html有一个嵌套状态,其中包括books_list.html或books_detail.html。

The url structure I'd like to have is:

我想要的网址结构是:

  • /books - Shows left/right sidepanels plus a list of books in the middle of the page.
  • / books - 显示左/右侧面板以及页面中间的书籍列表。
  • /books/1 - Shows left/right sidepanels plus the details for the book with ID 1 in the middle of the page (list of books is not displayed).
  • / books / 1 - 显示左/右侧面板以及页面中间ID为1的书的详细信息(不显示书籍列表)。

How can I set up my states to have the books.html template AND books_list.html template in the nested view when navigating to /books, but have books.html AND books_detail.html when navigating to /books/1 ?

如何在导航到/ books时将我的状态设置为嵌套视图中的books.html模板和books_list.html模板,但在导航到/ books / 1时有books.html AND books_detail.html?

I'm currently getting round this problem by having a "home" sub-state, but this means that I have to have /books/home, and /books displays no central content so is currently useless.

我目前通过拥有“家庭”子状态来解决这个问题,但这意味着我必须拥有/ books / home,并且/ books显示没有中心内容,因此目前无用。

.state('books', {
    url: '/books',
    templateUrl: CONFIG.static_url + '/html/books.html',
    ...
})
.state('books.home', {
    url: '/home',
    templateUrl: CONFIG.static_url + '/html/books_list.html',
    ...
})
.state('books.detail', {
    url: '/:bookId',
    templateUrl: CONFIG.static_url + '/html/books_detail.html',
    ...
})

3 个解决方案

#1


14  

I achieved what I needed by declaring an abstract state:

我通过声明一个抽象状态实现了我所需要的:

.state('books', {
    abstract: true,
    url: '/books',
    templateUrl: CONFIG.static_url + '/html/books.html',
    ...
})
.state('books.home', {
    url: '',
    templateUrl: CONFIG.static_url + '/html/books_list.html',
    ...
})
.state('books.detail', {
    url: '/:bookId',
    templateUrl: CONFIG.static_url + '/html/books_detail.html',
    ...
})

This means that /books loads both 'books' and 'books.home' states, and /books/1 loads both 'books' and 'books.detail' states, which is what I needed.

这意味着/ books加载'books'和'books.home'状态,/ books / 1加载'books'和'books.detail'状态,这就是我需要的。

#2


1  

I created working example here. This is following your needs, because there are only two levels of nesting.

我在这里创建了工作示例。这符合您的需求,因为只有两个级别的嵌套。

  • books is a parent for both children
    • books.home fills the middle erea - and is NOT parent of books.detail
    • books.home填充中间区域 - 并且不是books.detail的父级
    • books.detail replaces the list view - but that means that its $scope (books.home) is lost
    • books.detail取代了列表视图 - 但这意味着它的$ scope(books.home)丢失了
  • 书籍是两个孩子book.home的父母填充中间地区 - 并不是books.detail books.detail的父母替换列表视图 - 但这意味着它的$ scope(books.home)丢失了

State definition:

州定义:

.state('books', {
    url: '/books',
    views: {
      '@' : {
        templateUrl: 'layout.html',
      },
      'left@books' : { templateUrl: 'tpl.left.html',},
      'right@books' : { templateUrl: 'tpl.right.html',},
    },
  })
.state('books.home', {
    url: '/home',
    templateUrl: 'list.html',
  })
.state('books.detail', {
    url: '/:bookId',
    templateUrl: 'detail.html',
    controller: 'DetailCtrl'
  })

Check it here

在这里查看

But there is also a different approach, which I like more. The list view, is parent of its child, and therefore it could keep its $scope, while navigating among details. Similar stuff discussed here

但也有一种不同的方法,我更喜欢。列表视图是其子项的父项,因此它可以保留其$ scope,同时在详细信息中导航。这里讨论类似的东西

#3


-1  

maybe try it

也许试试吧

$urlRouterProvider.otherwise('/');
.....
.state('index', {
    url: '/',
    templateUrl: CONFIG.static_url + '/html/index.html',
    ...
})    

#1


14  

I achieved what I needed by declaring an abstract state:

我通过声明一个抽象状态实现了我所需要的:

.state('books', {
    abstract: true,
    url: '/books',
    templateUrl: CONFIG.static_url + '/html/books.html',
    ...
})
.state('books.home', {
    url: '',
    templateUrl: CONFIG.static_url + '/html/books_list.html',
    ...
})
.state('books.detail', {
    url: '/:bookId',
    templateUrl: CONFIG.static_url + '/html/books_detail.html',
    ...
})

This means that /books loads both 'books' and 'books.home' states, and /books/1 loads both 'books' and 'books.detail' states, which is what I needed.

这意味着/ books加载'books'和'books.home'状态,/ books / 1加载'books'和'books.detail'状态,这就是我需要的。

#2


1  

I created working example here. This is following your needs, because there are only two levels of nesting.

我在这里创建了工作示例。这符合您的需求,因为只有两个级别的嵌套。

  • books is a parent for both children
    • books.home fills the middle erea - and is NOT parent of books.detail
    • books.home填充中间区域 - 并且不是books.detail的父级
    • books.detail replaces the list view - but that means that its $scope (books.home) is lost
    • books.detail取代了列表视图 - 但这意味着它的$ scope(books.home)丢失了
  • 书籍是两个孩子book.home的父母填充中间地区 - 并不是books.detail books.detail的父母替换列表视图 - 但这意味着它的$ scope(books.home)丢失了

State definition:

州定义:

.state('books', {
    url: '/books',
    views: {
      '@' : {
        templateUrl: 'layout.html',
      },
      'left@books' : { templateUrl: 'tpl.left.html',},
      'right@books' : { templateUrl: 'tpl.right.html',},
    },
  })
.state('books.home', {
    url: '/home',
    templateUrl: 'list.html',
  })
.state('books.detail', {
    url: '/:bookId',
    templateUrl: 'detail.html',
    controller: 'DetailCtrl'
  })

Check it here

在这里查看

But there is also a different approach, which I like more. The list view, is parent of its child, and therefore it could keep its $scope, while navigating among details. Similar stuff discussed here

但也有一种不同的方法,我更喜欢。列表视图是其子项的父项,因此它可以保留其$ scope,同时在详细信息中导航。这里讨论类似的东西

#3


-1  

maybe try it

也许试试吧

$urlRouterProvider.otherwise('/');
.....
.state('index', {
    url: '/',
    templateUrl: CONFIG.static_url + '/html/index.html',
    ...
})