1. 程式人生 > >Angular4_監聽路由切換

Angular4_監聽路由切換

Title Service

在angular中,我們可以通過Title來設定頁面標題。我們從platform-browser匯入Title, 同時也匯入Router

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

匯入之後,我們在元件的建構函式中注入他們

@Component({
  selector: 'app-root',
  templateUrl: `
    <div>
      Hello world!
    </div>
  `
}) 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類有兩個方法,一個用來獲取頁面標題getTitle, 一個是用來設定頁面標題的setTitle

要更新頁面標題,我們可以簡單的呼叫setTitle方法:

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

這樣就可以設定我們的頁面標題了,但是很不優雅。我們接著往下看。

在AngularJS中,我們可以使用ui-router為每個路由新增一個自定義物件,自定義的物件在路由器的狀態鏈中繼承:

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

在Angular2+中,我們也可以為每個路由定義一個data物件,然後再在監聽路由變化時做一些額外的邏輯處理就可以實現動態設定頁面標題。首先,我們定義一個基本的路由:

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 }
  ]
}];

在這裡定義一個日曆應用,他有一個路由/calendar, 還有三個子路由, /all對應日曆列表頁,new對應新建日曆,:id對應日曆詳情。現在,我們定義一個data物件然後設定一個title屬性來作為每個頁面的標題。

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' } }
  ]
}];

好了,路由定義完了,現在我們看下如何監聽路由變化

Routing events

Angular路由配置非常簡單,但是路由通過Observables使用起來也非常強大。
我們可以在根元件中全域性監聽路由的變化:

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

我們要做的就是在導航結束時獲取到定義的資料然後設定頁面標題,可以檢查 NavigationStartRoutesRecognizedNavigationEnd 哪種事件是我們需要的方式,理想情況下NavigationEnd,我們可以這麼做:

this.router.events
  .subscribe((event) => {
    if (event instanceof NavigationEnd) { // 當導航成功結束時執行
      console.log('NavigationEnd:', event);
    }
  });

這樣我們就可以在導航成功結束時做一些邏輯了,因為Angular路由器是reactive響應式的,所以我們可以使用 RxJS 實現更多的邏輯,我們來匯入以下操作符:

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

現在我們已經添加了 filtermap 和 mergeMap 三個操作符,我們可以過濾出導航結束的事件:

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

其次,因為我們已經注入了Router類,我們可以使用 routerState 來獲取路由狀態樹得到最後一個導航成功的路由:

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

然而,一個更好的方式就是使用 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
  }
}

注入之後我們再來優化下:

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

我們使用 map 轉換了我們觀察到的內容,返回一個新的物件 this.activatedRoute 在 stream 流中繼續執行。 我們使用 filter(過濾出導航成功結束) 和 map(返回我們的路由狀態樹) 成功地返回我們想要的事件型別 NavigationEnd

接下來是最有意思的部分,我們將建立一個while迴圈遍歷狀態樹得到最後啟用的 route,然後將其作為結果返回到流中:

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

接下來我們可以通過路由配置的屬性來獲取相應的頁面標題。然後,我們還需要另外兩個運算子:

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,<router-outlet>
  .mergeMap(route => route.data)                // 獲取路由配置資料
  .subscribe((event) => {
    console.log('NavigationEnd:', event);
  });

現在我們 titleService 只需要實現:

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

相關推薦

Angular4_路由切換

Title Service在angular中,我們可以通過Title來設定頁面標題。我們從platform-browser匯入Title, 同時也匯入Router。import { Title } from '@angular/platform-browser'; impor

mint ui的tabBar路由變化實現tabBar切換

高亮顯示 get template this fault 購物 storage nta temp 說明 最近學習vue,使用了mint ui的tabBar,感覺好難受,結合 tab-container使用更難受,因為它不是根據路由來切換頁面的。mui與它基本相反,因此它能

Vue-- 路由變化,數據無法更新?

響應 被調用 數據驅動 後來 實例 無法 誤區 .com 來看   之前寫的Vue項目,有個問題困擾了好久。新聞板塊有推薦、精華、最新等幾個Tab,設想通過切換Tab,改變路由參數(get/news/:tab)去獲取對應數據,然後渲染到頁面(用的是同一套組件),問題來了:當

react-router搭配react-redux無法路由變化的問題

不必要 默認 cti 傳遞 通過 nbsp fun urn style 在react中,要將react組件連接到redux中,通常會這樣包裝組件 class Home extends Component { } function select(state)

Angular 路由變化

oca sta 實現 content 地址 root control $watch class var app = angular.module(‘Mywind‘,[‘ui.router‘]) //Angular 監聽路由變化 function run($ionicPla

vue 路由變化

scrip rip 不同的 bsp ted 監聽 brush 通過 deep 方法一:通過 watch // 監聽,當路由發生變化的時候執行 watch:{ $route(to,from){ console.log(to.path); } }, 或 /

vue利用watch路由變化

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <bod

js瀏覽器切換標籤欄事件

var OriginTitile = document.title, titleTime document.addEventListener('visibilitychange', function() {     if (document.hidden) {       

Vue路由引數及路由

路由引數 <!DOCTYPE html> <html lang="en"> <head> <title></title> <meta charset="UTF-8"> <meta n

vue 路由變化,dom載入完成後執行程式碼

watch 監聽路由變化,且dom渲染完成後執行函式 專案中在頁面中用到了footer,為了在頁面內容不超過螢幕高度時將footer定位置底,超過螢幕高度時不做定位,正常在內容最底部顯示,運用瞭如下方式問題:若不在dom渲染後執行,獲取的高度是不正確的.   watch: {

基於vue-cli的vue專案之路由3--watch路由

有時候我們需要監聽路由,做出某種操作。。。程式碼主要在app.vue上 1.hello.vue頁面//獲取一個引數,第五行顯示 <template> <div class="hello"> <!--{{ this.$route.param

android前後臺切換

公司的需求是這樣的,APP切換到前臺是向伺服器傳送資料,切換到後臺是也傳送資料。網上這方面的方法很多也很雜,還不好用,這裡介紹一種完美的解決方法,無論是back鍵還是home鍵切換到後臺都可以監聽,甚至通過後臺殺死APP程序都逃不過。 首先寫一個工具類:

vue 在.vue文件裏路由

com watch creat data user nag default port pan 監聽路由 watch $route vue項目中的App.vue 文件 <template> <div id="app"> <

Angular4 路由URL的變化

Angular 4檢測路由變化,可以使用router.events來監聽:支援的事件型別:NavigationStart:導航開始NavigationEnd:導航結束NavigationCancel:取消導航NavigationError:導航出錯RoutesRecoginz

全域性路由堆疊變化

![](https://img2020.cnblogs.com/other/467322/202009/467322-20200917071602199-1987970170.png) > **老孟導讀**:很多時候我們需要監聽路由堆疊的變化,這樣可以自定義路由堆疊、方便分析異常日誌等。 監聽路

瀏覽器標簽切換

hang list col add chang clas 自己的 自己 study document.addEventListener("visibilitychange", function () { document.title = document.

Android APP進入後臺或切換到前臺方案對比

api 5.0 等等 推薦一個 情況 lis 需要 推出 soc 在我們開發的過程中,經常會遇到需要我們判斷app進入後臺,或者切換到前臺的情況。比如我們想判斷app切換到前臺時,顯示一個解鎖界面,要求用戶輸入解鎖密碼才能繼續進行操作;我們想判斷app切換到後臺,記錄一下l

【Android】App應用前後臺切換的一種方法

Android本身並沒有提供監聽App的前後臺切換操作的方法。最近看到一種簡單巧妙的方法來監聽前後臺,這裡分享記錄一下。 一、Activity生命週期 我們知道在Android中,兩個Activity,分別為A和B。假設此時A在前臺,當A啟動B時,他們倆之間的生命週期關係如下,可

vue路由路由守衛

路由監聽: //當一個元件被複用的時候,那麼路由發生變化,但是頁面上面的資料不會發生變化 新建one.vue 元件 作為home的子元件,在home.vue 中寫遍歷渲染頁面 ,並用params傳參, one中 因為created只執行了一次,就接收都第一次傳的值,所以需要監聽 方案: 1、wat

Vue路由模式及

當然詳細情況還是看一下vue的官網咖 官網https://router.vuejs.org/zh/   hash模式下(預設) new VueRouter({ mode : ‘hash’, routes : [] }) window.addEventLi