• Angular2


    在基于Angualr的SPA中,路由是一个很重要的部分,它帮助我们更方便的实现页面上区域的内容的动态加载,不同tab的切换,同时及时更新浏览器地址栏的URN,使浏览器回退和前进能导航到历史访问的页面。

    (1) 基本配置

    1.1.配置base href

    在配置RoutesModule之前,我们需要再index.html里配置base href,这样,每一个路由的路径的前缀都是base href,应用的图片,文件夹,样式等资源都通过该base href来定位。

    //index.html
    <base href='/'></base>

      

    1.2.配置应用路由

    //app.routes.ts
    export const ROUTES: Routes = [ //根路径,通过base url:127.0.0.1:8888访问LogOnComponent, { path: '', component: LogOnComponent }, { path: 'chats', component: ChatsComponent }, { path: 'logon', component: LogOnComponent }, { path: 'fresh', component: FreshComponent }, /*base url下的路由,如果在初始化路由时使用hash:通过127.0.0.1:8888/#/friends访问 如果不使用hash,则通过127.0.0.1:8888/friends访问 */ { path: 'friends',component: FriendsComponent }, { path: 'other', //在访问127.0.0.1:8888/#/other时,再去加载一个模块,这就加快了应用初始化的速度 loadChildren: () => System.import('./components/sections/+detail') .then((comp: any) => comp.default), }, /*在跳转到任何一个路由之前会实例化该组件,若成功(找到目标路由),则跳转到目标路由 若失败,则跳转到 NoContentComponent ,我们可以将它理解为错误路由时需要跳转到的位置 */ { path: '**', component: NoContentComponent }, ];

      

    1.3.在应用模块中加载路由

    //app.module.ts
    import { ROUTES } from './app.routes'; import {RouterModule, NoPreloading} from '@angular/router'; @NgModule({ bootstrap: [ AppComponent ], imports: [ /*使用RouterModule.forRoot方法将路由配置加载到base url, useHash:true,则urn在浏览器显示为http://127.0.0.1:8083/#/friends useHash:false,则urn在浏览器显示为http://127.0.0.1:8083/friends 但其实,angular路由跳转都不会刷新整个页面,而是动态加载各个模块 enableTracing:true,在浏览器的输出窗口输出当前跳转操作的详细信息,如: NavigationEnd(id: 2, url: '/friends', urlAfterRedirects: '/friends'), preloadingStrategy: NoPreloading,允许组件懒加载,当应用加载成功之后,加载器便监听懒加载的路由的访问事件,一旦访问就去加载对应组件或模块 */ RouterModule.forRoot(ROUTES, { useHash: false,enableTracing:false, preloadingStrategy: NoPreloading }) ] })

      

    (2) 子模块的路由

    2.1 建立子模块

    //detail.module.ts
    import { CommonModule } from '@angular/common';
    import { FormsModule } from '@angular/forms';
    import { NgModule } from '@angular/core';
    import { DetailComponent } from './detail.component';
    import { FeedbackComponent } from '../../parts/feedback';
    import { FeedbackRoutingModule } from './routing/feedback-routing.module';
    import {AboutComponent} from "../about/about.component";
    //装饰一个NgModule
    @NgModule({
      declarations: [
    //引入该子模块的组件
        DetailComponent,
        FeedbackComponent,
        AboutComponent
      ],
      imports: [
    //此处导入CommonModule,而不是app.module中使用的BrowserModule,
    //如果BrowserModule被导入,就会报如下错误,可见BrowserModule用于加载根模块,CommonModule用于在懒加载的模块中提供angular的基本指令
    /*Error: BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.
    */
        CommonModule,
        FormsModule,
    //导入路由模块
        FeedbackRoutingModule
      ]
    })
    export default class OtherModule {
    
    }
    

      

    2.2 建立子应用模块的路由模块

    //detail-routing.module.ts
    import { ROUTES } from './feedback-routing.routes'; @NgModule({ imports:[ //使用RouterModule.forChild加载子路由模块 RouterModule.forChild(ROUTES) ], exports:[ //导出的DetailRoutingModule 中携带一个加载了ROUTES的RouterModule RouterModule ], providers:[ PeopleSvc, //到如一些作为服务的提供商 MemberShipResolver ] }) export class DetailRoutingModule{}

      

    2.3 配置子模块内部的路由

    //detail-routing.routes.ts
    import { Routes } from '@angular/router';
    import { FeedbackComponent } from '../../../../components/parts/feedback';
    import { DetailComponent } from '../detail.component';
    import { AboutComponent } from '../../about/about.component';
    import { MemberShipResolver } from '../../../../services/membership-resolver.service';
    export const ROUTES:Routes = [
      {
    //应用子模块路径
        path:'',
        data:{title:'Other'},
        component:DetailComponent,
        outlet:'primary',
        resolve: {
          pageInfo: MemberShipResolver
        },
    //子路由
        children:[
          { path:'logon',redirectTo:'' },
          {
            path: 'feedback',
            component: FeedbackComponent,
    /*定义实例化FeedbackComponent时的数据,可通过当前的ActivatedRoute对象来访问到 this.route.data.getValue()
    */
            data:{title:'User feedback'} ,
            resolve: {
              userInfoResult: MemberShipResolver
            }
          },
          {
            path:'about',
            component:AboutComponent
          }
        ]
      }
    ];
    

      

    (3) 路由分析器

    Router Resolver其实是一个服务,在跳转到某个路由时,该service可获取到当前ActivatedRoute,获取其携带的data,这里可以提前去服务端获取一些数据,或者做一些数据转换之后再进行组件的实例化和渲染。比如,当用户将要跳转到应用的反馈页面填写反馈时,我们可以通过一个membership-resolver去检查是否为登录用户,如果不是,则跳转到登录页面,如果是则显示历史反馈和反馈填写表单入口。

    3.1 建立membership-resolver

    //membership-resolver.service.ts
    import { Injectable } from '@angular/core';
    import { FeedbackSvc } from './feedbackSvc';
    import {Router, RouterStateSnapshot, ActivatedRouteSnapshot, Resolve} from "@angular/router";
    import {ClientState} from "./client-state.service";
    @Injectable()
    export class MemberShipResolver implements Resolve<string>{
    //clientState:ClientState 该服务提供当前登录用户的信息
      constructor(private router: Router,private peopleSvc:PeopleSvc,private clientState:ClientState)  {
    
    
      }
    
    //实现 Resolve接口的resolve方法
    resolve(route:ActivatedRouteSnapshot,state:RouterStateSnapshot):Promise<string>{
        let me = this;
        let clientUser = this.clientState.get('user');
        let prom = new Promise(function(resolve,reject){
    //如果当前登录用户为null,则跳转到logon
          if(clientUser === null){
            me.router.navigate(['./logon']);
            resolve(null);
          }else{
    //获取所有feedback
            me.feedbackSvc.getAll().then((data)=>{
              if(data !== null){
                resolve(data);
              }else{
                resolve(null);
              }
            });
          }
        });
        return prom;
      }
    }
    

      

    3.2 制定分析器解析的数据标识

    //feedback.routing.ts
    { path: 'feedback', component: FeedbackComponent, data:{title:'User feedback'} , resolve: { //定义feedbackResult的分析器,该分析器异步返回的数据将添加到data下 feedbackResult: MemberShipResolver } }

      

    3.3 监控分析器数据变化

    //feedback.component.ts
    import { Component } from '@angular/core';
    import { FeedbackSvc } from './feedbackSvc';
    import {Router, ActivatedRoute} from "@angular/router";
    import {Feedback} from "../../../models/business/Feedback";
    import {User} from "../../../models/business/User";
    import {ClientState} from "../../../services/client-state.service";
    @Component({
      selector:'feedback',
      templateUrl:'feedback.component.html',
      styleUrls:[ 'feedback.component.css' ],
      providers:[ FeedbackSvc ]
    })
    
    export class FeedbackComponent{
      private allFeedback:Feedback[] = [];
      constructor(public feedbackSvc:FeedbackSvc, private router: Router,private route:ActivatedRoute,private client:ClientState){
    
      }
    
    
      ngOnInit() {
        let _this = this;
    //注册当前路由携带的数据的变化回调
        this.route.data.subscribe((data:Feedback[]) => {
          if(data !== null){
    //将分析器返回的数据作为component的数据
            _this.allFeedback = data;
          }
        });
      }
    }
    

      

     

  • 相关阅读:
    Boost练习程序(multi_index_container)
    mathematica练习程序(图像取反)
    【转】媒体播放器三大底层架构
    CentOS安装中文支持
    Retrofit2文件上传下载及其进度显示
    Andorid面试问题整理
    5分钟实现Android中更换头像功能
    Android中突发情况Activity数据的保存和恢复
    5分钟让你学会用最高效的工具解析所有Json
    android http 和https请求
  • 原文地址:https://www.cnblogs.com/wzcblogs/p/6290119.html
Copyright © 2020-2023  润新知