成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Angular 2+ 監(jiān)聽路由變化動(dòng)態(tài)設(shè)置頁面標(biāo)題

entner / 3181人閱讀

摘要:今天我們實(shí)現(xiàn)單頁面應(yīng)用中路由變化設(shè)置頁面標(biāo)題,來優(yōu)化用戶的用戶體驗(yàn)。在中,解決起來要比容易得多,我們可以通過注入一個(gè),在路由變化事件中使用提供的來動(dòng)態(tài)更新頁面標(biāo)題。

現(xiàn)在很多web網(wǎng)站都采用了SPA單頁應(yīng)用,單頁面有很多優(yōu)點(diǎn):用戶體驗(yàn)好、應(yīng)用響應(yīng)快、對(duì)服務(wù)器壓力小 等等。同時(shí)也有一些缺點(diǎn):首次加載資源太多,不利于SEO,前進(jìn)、后退、地址欄需要手動(dòng)管理。今天我們實(shí)現(xiàn)Angular單頁面應(yīng)用中路由變化設(shè)置頁面標(biāo)題,來優(yōu)化用戶的用戶體驗(yàn)??梢韵热ゾ蚪鹂聪滦Ч?。稀土掘金

在AngularJS(1.x)中動(dòng)態(tài)設(shè)置頁面標(biāo)題通常是通過一個(gè)全局$rootScope對(duì)象來完成的,通過$rootScope對(duì)象監(jiān)聽路由變化獲取當(dāng)前路由信息并映射到頁面標(biāo)題。在Angular(v2 +)中,解決起來要比1.x容易得多,我們可以通過注入一個(gè)provider,在路由變化事件中使用provider提供的API來動(dòng)態(tài)更新頁面標(biāo)題。

Title Service

在angular中,我們可以通過Title來設(shè)置頁面標(biāo)題。我們從platform-browser導(dǎo)入Title, 同時(shí)也導(dǎo)入Router。

import { Title } from "@angular/platform-browser";
import { Router } from "@angular/router";

導(dǎo)入之后,我們?cè)诮M件的構(gòu)造函數(shù)中注入他們

@Component({
  selector: "app-root",
  templateUrl: `
    
Hello world!
` }) export class AppComponent { constructor(private router: Router, private titleService: Title) {} }

在使用Title之前,我們先看下Title是如何定義的

export class Title {
  /**
   * Get the title of the current HTML document.
   * @returns {string}
   */
  getTitle(): string { return getDOM().getTitle(); }

  /**
   * Set the title of the current HTML document.
   * @param newTitle
   */
  setTitle(newTitle: string) { getDOM().setTitle(newTitle); }
}

Title類有兩個(gè)方法,一個(gè)用來獲取頁面標(biāo)題getTitle, 一個(gè)是用來設(shè)置頁面標(biāo)題的setTitle

要更新頁面標(biāo)題,我們可以簡(jiǎn)單的調(diào)用setTitle方法:

@Component({...})
export class AppComponent implements OnInit {
  constructor(private router: Router, private titleService: Title) {}
  ngOnInit() {
    this.titleService.setTitle("My awesome app");
  }
}

這樣就可以設(shè)置我們的頁面標(biāo)題了,但是很不優(yōu)雅。我們接著往下看。

在AngularJS中,我們可以使用ui-router為每個(gè)路由添加一個(gè)自定義對(duì)象,自定義的對(duì)象在路由器的狀態(tài)鏈中繼承:

// AngularJS 1.x + ui-router
.config(function ($stateProvider) {
  $stateProvider
    .state("about", {
      url: "/about",
      component: "about",
      data: {
        title: "About page"
      }
    });
});

在Angular2+中,我們也可以為每個(gè)路由定義一個(gè)data對(duì)象,然后再在監(jiān)聽路由變化時(shí)做一些額外的邏輯處理就可以實(shí)現(xiàn)動(dòng)態(tài)設(shè)置頁面標(biāo)題。首先,我們定義一個(gè)基本的路由:

const routes: Routes = [{
  path: "calendar",
  component: CalendarComponent,
  children: [
    { path: "", redirectTo: "new", pathMatch: "full" },
    { path: "all", component: CalendarListComponent },
    { path: "new", component: CalendarEventComponent },
    { path: ":id", component: CalendarEventComponent }
  ]
}];

在這里定義一個(gè)日歷應(yīng)用,他有一個(gè)路由/calendar, 還有三個(gè)子路由, /all對(duì)應(yīng)日歷列表頁,new對(duì)應(yīng)新建日歷,:id對(duì)應(yīng)日歷詳情?,F(xiàn)在,我們定義一個(gè)data對(duì)象然后設(shè)置一個(gè)title屬性來作為每個(gè)頁面的標(biāo)題。

const routes: Routes = [{
  path: "calendar",
  component: CalendarComponent,
  children: [
    { path: "", redirectTo: "new", pathMatch: "full" },
    { path: "all", component: CalendarListComponent, data: { title: "My Calendar" } },
    { path: "new", component: CalendarEventComponent, data: { title: "New Calendar Entry" } },
    { path: ":id", component: CalendarEventComponent, data: { title: "Calendar Entry" } }
  ]
}];

好了,路由定義完了,現(xiàn)在我們看下如何監(jiān)聽路由變化

Routing events

Angular路由配置非常簡(jiǎn)單,但是路由通過Observables使用起來也非常強(qiáng)大。
我們可以在根組件中全局監(jiān)聽路由的變化:

ngOnInit() {
  this.router.events
    .subscribe((event) => {
      // example: NavigationStart, RoutesRecognized, NavigationEnd
      console.log(event);
    });
}

我們要做的就是在導(dǎo)航結(jié)束時(shí)獲取到定義的數(shù)據(jù)然后設(shè)置頁面標(biāo)題,可以檢查 NavigationStart, RoutesRecognized, NavigationEnd 哪種事件是我們需要的方式,理想情況下NavigationEnd,我們可以這么做:

this.router.events
  .subscribe((event) => {
    if (event instanceof NavigationEnd) { // 當(dāng)導(dǎo)航成功結(jié)束時(shí)執(zhí)行
      console.log("NavigationEnd:", event);
    }
  });

這樣我們就可以在導(dǎo)航成功結(jié)束時(shí)做一些邏輯了,因?yàn)锳ngular路由器是reactive響應(yīng)式的,所以我們可以使用 RxJS 實(shí)現(xiàn)更多的邏輯,我們來導(dǎo)入以下操作符:

import "rxjs/add/operator/filter";
import "rxjs/add/operator/map";
import "rxjs/add/operator/mergeMap";

現(xiàn)在我們已經(jīng)添加了 filtermapmergeMap 三個(gè)操作符,我們可以過濾出導(dǎo)航結(jié)束的事件:

this.router.events
  .filter(event => event instanceof NavigationEnd)
  .subscribe((event) => {
    console.log("NavigationEnd:", event);
  });

其次,因?yàn)槲覀円呀?jīng)注入了Router類,我們可以使用 routerState 來獲取路由狀態(tài)樹得到最后一個(gè)導(dǎo)航成功的路由:

this.router.events
  .filter(event => event instanceof NavigationEnd)
  .map(() => this.router.routerState.root)
  .subscribe((event) => {
    console.log("NavigationEnd:", event);
  });

然而,一個(gè)更好的方式就是使用 ActivatedRoute 來代替 routerState.root, 我們可以將其ActivatedRoute注入類中:

import { Router, NavigationEnd, ActivatedRoute } from "@angular/router";

@Component({...})
export class AppComponent implements OnInit {
  constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute,
    private titleService: Title
  ) {}
  ngOnInit() {
    // our code is in here
  }
}

注入之后我們?cè)賮韮?yōu)化下:

this.router.events
  .filter(event => event instanceof NavigationEnd)
  .map(() => this.activatedRoute)
  .subscribe((event) => {
    console.log("NavigationEnd:", event);
  });

我們使用 map 轉(zhuǎn)換了我們觀察到的內(nèi)容,返回一個(gè)新的對(duì)象 this.activatedRoutestream 流中繼續(xù)執(zhí)行。 我們使用 filter(過濾出導(dǎo)航成功結(jié)束)map(返回我們的路由狀態(tài)樹) 成功地返回我們想要的事件類型 NavigationEnd。

接下來是最有意思的部分,我們將創(chuàng)建一個(gè)while循環(huán)遍歷狀態(tài)樹得到最后激活的 route,然后將其作為結(jié)果返回到流中:

this.router.events
  .filter(event => event instanceof NavigationEnd)
  .map(() => this.activatedRoute)
  .map(route => {
    while (route.firstChild) route = route.firstChild;
    return route;
  })
  .subscribe((event) => {
    console.log("NavigationEnd:", event);
  });

接下來我們可以通過路由配置的屬性來獲取相應(yīng)的頁面標(biāo)題。然后,我們還需要另外兩個(gè)運(yùn)算符:

this.router.events
  .filter(event => event instanceof NavigationEnd)
  .map(() => this.activatedRoute)
  .map(route => {
    while (route.firstChild) route = route.firstChild;
    return route;
  })
  .filter(route => route.outlet === "primary")  // 過濾出未命名的outlet,
  .mergeMap(route => route.data)                // 獲取路由配置數(shù)據(jù)
  .subscribe((event) => {
    console.log("NavigationEnd:", event);
  });

現(xiàn)在我們 titleService 只需要實(shí)現(xiàn):

.subscribe((event) => this.titleService.setTitle(event["title"]));

下面看一下最終代碼:

import "rxjs/add/operator/filter";
import "rxjs/add/operator/map";
import "rxjs/add/operator/mergeMap";

import { Component, OnInit } from "@angular/core";
import { Router, NavigationEnd, ActivatedRoute } from "@angular/router";
import { Title } from "@angular/platform-browser";

@Component({...})
export class AppComponent implements OnInit {
  constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute,
    private titleService: Title
  ) {}
  ngOnInit() {
    this.router.events
      .filter(event => event instanceof NavigationEnd)
      .map(() => this.activatedRoute)
      .map(route => {
        while (route.firstChild) route = route.firstChild;
        return route;
      })
      .filter(route => route.outlet === "primary")
      .mergeMap(route => route.data)
      .subscribe((event) => this.titleService.setTitle(event["title"]));
  }
}

本文翻譯自dynamic-page-titles-angular-2-router-events, 本人水平有限,如果有翻譯不好的地方歡迎大家聯(lián)系我

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/83725.html

相關(guān)文章

  • Angular頁面動(dòng)態(tài)修改title[兼容微信]

    摘要:文件定義在通過路由定義標(biāo)題首頁首頁通過動(dòng)態(tài)調(diào)用標(biāo)題在里面定義通過監(jiān)聽的變化來動(dòng)態(tài)調(diào)用標(biāo)題首頁首頁文件在里同過頭部里的動(dòng)態(tài)調(diào)用首頁 js文件 定義module var app = angular.module(app, [ngRoute]); 在config通過路由定義標(biāo)題 app.config([$routeProvider, $locationProvider, function ...

    Cheriselalala 評(píng)論0 收藏0
  • AngularJs功能(九)--路由

    摘要:該內(nèi)的內(nèi)容會(huì)根據(jù)路由的變化而變化。配置,用來定義路由規(guī)則。由此我們就需要另一個(gè)第三方路由模塊,叫做,當(dāng)然它是基于開發(fā)的。造成這種現(xiàn)象的最根本原因路由沒有明確的父子層級(jí)關(guān)系。監(jiān)聽路由路由狀態(tài)發(fā)生改變時(shí)可以通過監(jiān)聽,通過注入實(shí)現(xiàn)狀態(tài)的管理。 何為路由 路由機(jī)制運(yùn)可以實(shí)現(xiàn)多視圖的單頁Web應(yīng)用(single page web application,SPA)。 單頁應(yīng)用在使用期間不會(huì)重新加載...

    mingde 評(píng)論0 收藏0
  • AngularJs

    摘要:當(dāng)左右服務(wù)都被解析并返回時(shí),會(huì)以服務(wù)為參數(shù)去調(diào)用組件的構(gòu)造函數(shù)。發(fā)送或廣播的消息應(yīng)該限定在最小的作用域。置頂一個(gè)通過,發(fā)送的消息列表并且窒息的管理以防止命名沖突在需要格式化數(shù)據(jù)時(shí),將格式 angular 數(shù)據(jù)雙向綁定的框架 提供數(shù)據(jù)綁定,DOM指令。angular,定義了一套規(guī)則,開發(fā)中就必須遵守規(guī)則,這套規(guī)則為項(xiàng)目提供了一套解決方案。 模塊,組件,模板,元數(shù)據(jù),數(shù)據(jù)綁定, 指令,服務(wù)...

    sf190404 評(píng)論0 收藏0
  • Angular 4 簡(jiǎn)單入門筆記

    摘要:首先,我們需要在入口頁面的中配置根路徑然后創(chuàng)建一個(gè)路由模塊路由配置在主模塊中導(dǎo)入配置好的路由模塊而在頁面中需要一個(gè)容器去承載上面代碼中的定義了用戶點(diǎn)擊后的路由跳轉(zhuǎn),定義該路由激活時(shí)的樣式類。 剛實(shí)習(xí)的時(shí)候用過AngularJS,那時(shí)候真的是連原生JavaScript都不會(huì)寫,依樣畫葫蘆做了幾個(gè)管理后臺(tái)。然后突然換項(xiàng)目了,AngularJS就不寫了,感覺前前后后接觸了一年多的Angula...

    whlong 評(píng)論0 收藏0
  • 自己動(dòng)手實(shí)現(xiàn)一個(gè)前端路由

    摘要:監(jiān)聽的變動(dòng)省略其他代碼省略其他代碼這樣,我們就初步實(shí)現(xiàn)了一個(gè)路由,那么接下來,我們來看看路由怎么實(shí)現(xiàn)。 前言 用過現(xiàn)代前端框架的同學(xué),對(duì)前端路由一定不陌生, vue, react, angular 都有自己的 router, 那么你對(duì) router 的工作原理了解嗎?如果還不了解, 那么請(qǐng)跟我一起來手寫一個(gè)簡(jiǎn)單的前端路由, 順便了解一下. 實(shí)現(xiàn)路由的2種方式 hash模式 histo...

    longshengwang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<