AngularJS UI-Router多页面

14
Angular是一个单页应用程序(SPA),这很好,但如果我需要一些与index.html无关的其他页面,该怎么办?如何通过UI-Router状态和不同的ui-views实现?
例如,我有index.html:
<!DOCTYPE html>
<html data-ng-app="npAdmin">
<head>
...
</head>
<body>
   <header>
      <data-user-profile class="user-profile"></data-user-profile>
  </header>

  <section class="content-wrapper">
      <aside data-main-menu></aside>
      <div class="main-content" data-ui-view></div>
  </section>

  <footer class="row"></footer>
...
</body>
</html>

app.js:

var app = angular.module('npAdmin', ['ui.router']);

app.config(['$httpProvider', '$stateProvider', '$urlRouterProvider', function($httpProvider, $stateProvider, $urlRouterProvider) {

    $stateProvider
    .state('dashboard', {
        url: '/dashboard',
        templateUrl: '/app/dashboard/dashboard.html',
        controller: 'DashboardCtrl'
    })
    .state('crm', {
        url: '/crm',
        templateUrl: '/app/crm/crm.html',
        controller: 'CrmCtrl'
    })
...

现在我需要 login.html 页面,它与 index.html 完全不同(不需要 index 的页头、页脚和侧边栏),但是 config stateProvider 只会查找 index.html 中的 ui-view 并通过状态将其更改为相应的内容。如何将 login.html 合并?

看起来并不难,但我还是不懂。

2个回答

15

如你所料,这并不难,有一个plunker示例。

窍门在于将所有视图共用的内容移动到特定模板中,例如common.html,并创建抽象状态。换句话说,index.html 将保持清晰:

<body>

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

并且它之前的内容 (index.html 的内容) 将被移动到 common.html。状态定义可能如下所示:

$stateProvider
  .state('common', {
    templateUrl: 'tpl.common.html',
    abstract: true,
  })
  .state('dashboard', {
    url: '/dashboard',
    parent: 'common',
    ...
  })
  .state('crm', { 
    url: '/crm',
    parent: 'common',
    ...
  })
  .state('login', {
    url: '/login',
    templateUrl: 'tpl.login.html',
  });

$urlRouterProvider.otherwise('/crm');

有趣的是,我们引入了抽象状态而没有使用URL。所以所有当前逻辑都将保持不变,只是抽象状态将扮演布局模板的角色。

在此处查看更多: 示例


现在我知道如何使用抽象状态属性了。谢谢。 - swolfish
很高兴看到这个消息;) ui-router 真的非常强大和好用... 好好享受它吧 ;) - Radim Köhler
@KillABug 我建议你提出问题并展示更多细节,这样你肯定会得到答案。或者告诉我,我也可以帮你检查。评论不适合调查你的代码为什么无法工作... 这样是否有意义? - Radim Köhler
@KillABug,如果我知道的话,我会帮忙的。但是你的问题会引起比我更多的人的关注,所以你肯定会得到答案...我相信。 - Radim Köhler
@RadimKöhler http://stackoverflow.com/questions/29073389/loading-angular-js-internal-routes-and-controllers - KillABug

4
我以前也遇到过这个问题,如果你感兴趣可以参考THIS。在该链接中,我还处理了returnUrl401 http状态码(如果用户未获授权)。

针对您的情况,我建议您按照以下方式设计应用程序:

index.html:

<!DOCTYPE html>
<html data-ng-app="npAdmin">
<head>
...
</head>
<body data-ui-view>

</body>
...
</html>

main.html:

  <header>
      <data-user-profile class="user-profile"></data-user-profile>
  </header>

  <section class="content-wrapper">
      <aside data-main-menu></aside>
      <div class="main-content" data-ui-view></div>
  </section>

  <footer class="row"></footer>

登陆页面

(包含此视图的HTML)

App.js:

var app = angular.module('npAdmin', ['ui.router']);

app.config(['$httpProvider', '$stateProvider', '$urlRouterProvider', function($httpProvider, $stateProvider, $urlRouterProvider) {

    $stateProvider
    .state('login',{
       url:"/login",
       templateUrl: '/app/login.html',
       controller: 'LoginCtrl'
     })
    .state('main',function(){
       url:"/",
       templateUrl: '/app/main.html',
       controller: 'MainCtrl',
       abstract: true //you could use abstract state or not depending on your design 
    })
    .state('main.dashboard', { //inherit from your main
        url: '/dashboard',
        templateUrl: '/app/dashboard/dashboard.html',
        controller: 'DashboardCtrl'
    })
    .state('main.crm', { //inherit from your main
        url: '/crm',
        templateUrl: '/app/crm/crm.html',
        controller: 'CrmCtrl'
    })

解释:

由于Angular是单页应用程序(SPA),因此您的index.html应该包含应用程序的所有视图。有多种方法可以确保这一点。在此示例中,login也是应用程序中的状态,与您的main分开。通过利用Angular路由器中的状态继承,您可以进一步拥有main中的子状态,例如在此情况下的dashboardcrm


1
除此之外,如果你要有一个独立的登录页面,请确保实现一个身份验证检查服务。这样,如果用户没有登录,他们将被重定向到登录页面。观看此视频以了解基本实现:http://youtu.be/hqAyiqUs93c - Ed B
@Ed B:当然,因为这不包含在问题中。我们将为所有请求检查,而不仅仅是登录页面。 - Khanh TO
非常感谢,回答非常详尽,但有一些小错误。Radim的抽象状态解决方案似乎是完美的解决方案。 - swolfish
@swolfish:我没有测试这段代码,只是提供了想法。正如我所说,有多种方法可以实现。这只是设计问题。 - Khanh TO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接