Trong Angular, 'pathmatch: full' là gì và nó có tác dụng gì?


101

Ở đây, nó sử dụng pathmatch là đầy đủ và khi tôi xóa pathmatch này, nó thậm chí không tải ứng dụng hoặc chạy dự án

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';

import { AppComponent }  from './app.component';
import { WelcomeComponent } from './home/welcome.component';

/* Feature Modules */
import { ProductModule } from './products/product.module';

@NgModule({
  imports: [
    BrowserModule,
    HttpModule,
    RouterModule.forRoot([
      { path: 'welcome', component: WelcomeComponent },
      { path: '', redirectTo: 'welcome', pathMatch: 'full' },
      { path: '**', redirectTo: 'welcome', pathMatch: 'full' }
    ]),
    ProductModule
  ],
  declarations: [
    AppComponent,
    WelcomeComponent
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

Câu trả lời:


110
RouterModule.forRoot([
      { path: 'welcome', component: WelcomeComponent },
      { path: '', redirectTo: 'welcome', pathMatch: 'full' },
      { path: '**', component: 'pageNotFoundComponent' }
    ])

Trường hợp 1 pathMatch:'full' : Trong trường hợp này, khi ứng dụng được khởi chạy trên localhost:4200(hoặc một số máy chủ), trang mặc định sẽ là màn hình chào mừng, vì url sẽ làhttps://localhost:4200/

Nếu https://localhost:4200/gibberishđiều này sẽ chuyển hướng đến màn hình pageNotFoundpath:'**'ký tự đại diện

Trường hợp 2 pathMatch:'prefix' :

Nếu các tuyến có { path: '', redirectTo: 'welcome', pathMatch: 'prefix' }, bây giờ nó sẽ không bao giờ đến được tuyến ký tự đại diện vì mọi url sẽ khớp path:''được xác định.


xin chào, cảm ơn bạn đã giải thích rõ ràng cho ví dụ này, nhưng bạn có thể đưa ra một ví dụ khác với loại tuyến đường khác để làm cho nó hoàn toàn rõ ràng được không? (như sử dụng một ví dụ với các tuyến đường dành cho trẻ em, v.v.). cảm ơn
sohaieb

thật sự rất hay, thưa ông nhưng bạn có thể cho tôi biết cách cấu hình với 2 bố cục khác nhau không. như bố cục bên trong và bố cục bên ngoài>
Kapil soni

87

pathMatch = 'full' dẫn đến một lần truy cập tuyến khi các phân đoạn còn lại, chưa đối sánh của URL khớp là đường dẫn tiền tố

pathMatch = 'prefix'cho bộ định tuyến biết để khớp với tuyến chuyển hướng khi URL còn lại bắt đầu với đường dẫn tiền tố của tuyến chuyển hướng.

Tham khảo: https://angular.io/guide/router#set-up-redirects

pathMatch: 'full' nghĩa là toàn bộ đường dẫn URL cần phải khớp và được sử dụng bởi thuật toán đối sánh tuyến đường.

pathMatch: 'prefix' có nghĩa là, tuyến đầu tiên trong đó đường dẫn khớp với phần đầu của URL được chọn, nhưng sau đó thuật toán đối sánh tuyến tiếp tục tìm kiếm các tuyến con phù hợp mà phần còn lại của URL khớp.


24

Mặc dù đúng về mặt kỹ thuật, nhưng các câu trả lời khác sẽ được hưởng lợi từ lời giải thích về đối sánh URL-to-route của Angular. Tôi không nghĩ rằng bạn hoàn toàn có thể hiểu được điều gì pathMatch: fullxảy ra nếu bạn không biết bộ định tuyến hoạt động như thế nào ngay từ đầu.


Đầu tiên chúng ta hãy xác định một vài điều cơ bản. Chúng tôi sẽ sử dụng URL này là một ví dụ: /users/james/articles?from=134#section.

  1. Nó có thể rõ ràng nhưng trước tiên hãy chỉ ra rằng các tham số truy vấn ( ?from=134) và các đoạn ( #section) không đóng bất kỳ vai trò nào trong đối sánh đường dẫn . Chỉ url cơ sở ( /users/james/articles) là quan trọng.

  2. Angular chia các URL thành các phân đoạn . Tất nhiên, các phân đoạn của /users/james/articlesusers, jamesarticles.

  3. Cấu hình bộ định tuyến là một cấu trúc cây với một nút gốc duy nhất. Mỗi Routeđối tượng là một nút, có thể có childrencác nút, lần lượt có thể có các nút khác childrenhoặc là các nút lá.

Mục tiêu của bộ định tuyến là tìm một nhánh cấu hình bộ định tuyến , bắt đầu từ nút gốc, sẽ khớp chính xác với tất cả các phân đoạn (!!!) của URL. Đây là điều tối quan trọng! Nếu Angular không tìm thấy nhánh cấu hình tuyến đường có thể khớp với toàn bộ URL - không hơn không kém - nó sẽ không hiển thị bất kỳ thứ gì .

Ví dụ: nếu URL mục tiêu của bạn là /a/b/cnhưng bộ định tuyến chỉ có thể khớp với một trong hai /a/bhoặc /a/b/c/d, thì không khớp và ứng dụng sẽ không hiển thị bất kỳ thứ gì.

Cuối cùng, các tuyến đường có redirectTohoạt động hơi khác so với các tuyến đường thông thường, và dường như đối với tôi, chúng sẽ là nơi duy nhất mà mọi người thực sự muốn sử dụng pathMatch: full. Nhưng chúng ta sẽ làm điều này sau.

Đối prefixsánh đường dẫn ( ) mặc định

Lý do đằng sau tên prefixnày là cấu hình tuyến đường như vậy sẽ kiểm tra xem cấu hình pathđược định cấu hình có phải là tiền tố của các phân đoạn URL còn lại hay không. Tuy nhiên, bộ định tuyến chỉ có thể khớp các phân đoạn đầy đủ , điều này làm cho việc đặt tên này hơi khó hiểu.

Dù sao, hãy nói rằng đây là cấu hình bộ định tuyến cấp gốc của chúng tôi:

const routes: Routes = [
  {
    path: 'products',
    children: [
      {
        path: ':productID',
        component: ProductComponent,
      },
    ],
  },
  {
    path: ':other',
    children: [
      {
        path: 'tricks',
        component: TricksComponent,
      },
    ],
  },
  {
    path: 'user',
    component: UsersonComponent,
  },
  {
    path: 'users',
    children: [
      {
        path: 'permissions',
        component: UsersPermissionsComponent,
      },
      {
        path: ':userID',
        children: [
          {
            path: 'comments',
            component: UserCommentsComponent,
          },
          {
            path: 'articles',
            component: UserArticlesComponent,
          },
        ],
      },
    ],
  },
];

Lưu ý rằng mọi Routeđối tượng ở đây đều sử dụng chiến lược đối sánh mặc định prefix. Chiến lược này có nghĩa là bộ định tuyến lặp lại toàn bộ cây cấu hình và cố gắng đối sánh nó với phân đoạn URL mục tiêu theo từng phân đoạn cho đến khi URL được khớp hoàn toàn . Đây là cách nó sẽ được thực hiện cho ví dụ này:

  1. Lặp lại trên mảng gốc để tìm kiếm kết hợp chính xác cho phân đoạn URL đầu tiên - users.
  2. 'products' !== 'users', vì vậy hãy bỏ qua nhánh đó. Lưu ý rằng chúng tôi đang sử dụng kiểm tra bình đẳng thay vì kiểm tra .startsWith()hoặc .includes()- chỉ tính các kết quả phù hợp phân đoạn đầy đủ!
  3. :otherkhớp với bất kỳ giá trị nào, vì vậy nó là một trận đấu. Tuy nhiên, URL đích vẫn chưa được khớp hoàn toàn (chúng tôi vẫn cần phải khớp jamesarticles), do đó, bộ định tuyến sẽ tìm kiếm trẻ em.
    • Các đứa con duy nhất của :othertricks, đó là !== 'james', do đó không phải là một trận đấu.
  4. Angular sau đó quay trở lại mảng gốc và tiếp tục từ đó.
  5. 'user' !== 'users, bỏ qua nhánh.
  6. 'users' === 'users- phân đoạn phù hợp. Tuy nhiên, đây vẫn chưa phải là một đối sánh đầy đủ, do đó chúng ta cần tìm kiếm các con (giống như ở bước 3).
    • 'permissions' !== 'james', bỏ qua nó.
    • :userIDphù hợp với bất kỳ thứ gì, do đó chúng tôi có một đối sánh cho jamesphân khúc. Tuy nhiên, đây vẫn chưa phải là một trận đấu đầy đủ, do đó chúng tôi cần tìm kiếm một con phù hợp articles.
      1. Chúng tôi có thể thấy rằng :userIDcó một tuyến con articles, mang lại cho chúng tôi một trận đấu đầy đủ! Do đó, ứng dụng kết xuất UserArticlesComponent.

Đối sánh URL đầy đủ ( full)

ví dụ 1

Hãy tưởng tượng bây giờ usersđối tượng cấu hình tuyến đường trông như thế này:

{
  path: 'users',
  component: UsersComponent,
  pathMatch: 'full',
  children: [
    {
      path: 'permissions',
      component: UsersPermissionsComponent,
    },
    {
      path: ':userID',
      component: UserComponent,
      children: [
        {
          path: 'comments',
          component: UserCommentsComponent,
        },
        {
          path: 'articles',
          component: UserArticlesComponent,
        },
      ],
    },
  ],
}

Lưu ý việc sử dụng pathMatch: full. Nếu đúng như vậy, các bước 1-5 sẽ giống nhau, tuy nhiên bước 6 sẽ khác:

  1. 'users' !== 'users/james/articles- phân đoạn không khớp vì cấu hình đường dẫn usersvới pathMatch: fullkhông khớp với URL đầy đủ users/james/articles.
  2. Vì không có trận đấu, chúng tôi đang bỏ qua nhánh này.
  3. Tại thời điểm này, chúng tôi đã kết thúc cấu hình bộ định tuyến mà không tìm thấy kết quả phù hợp. Ứng dụng không hiển thị .

Ví dụ 2

Điều gì sẽ xảy ra nếu chúng tôi có cái này thay thế:

{
  path: 'users/:userID',
  component: UsersComponent,
  pathMatch: 'full',
  children: [
    {
      path: 'comments',
      component: UserCommentsComponent,
    },
    {
      path: 'articles',
      component: UserArticlesComponent,
    },
  ],
}

users/:userIDchỉ với các pathMatch: fullkết quả phù hợp, users/jamesdo đó một lần nữa nó không phù hợp và ứng dụng không hiển thị gì.

Ví dụ 3

Hãy xem xét điều này:

{
  path: 'users',
  children: [
    {
      path: 'permissions',
      component: UsersPermissionsComponent,
    },
    {
      path: ':userID',
      component: UserComponent,
      pathMatch: 'full',
      children: [
        {
          path: 'comments',
          component: UserCommentsComponent,
        },
        {
          path: 'articles',
          component: UserArticlesComponent,
        },
      ],
    },
  ],
}

Trong trường hợp này:

  1. 'users' === 'users- phân khúc khớp, nhưng james/articlesvẫn chưa khớp . Hãy tìm kiếm trẻ em.
    • 'permissions' !== 'james' - nhảy.
    • :userID'chỉ có thể khớp với một phân đoạn duy nhất james. Tuy nhiên, đó là một pathMatch: fulltuyến đường và nó phải khớp james/articles(toàn bộ URL còn lại). Nó không thể làm điều đó và do đó nó không phù hợp (vì vậy chúng tôi bỏ qua nhánh này)!
  2. Một lần nữa, chúng tôi không tìm thấy bất kỳ kết quả phù hợp nào cho URL và ứng dụng không hiển thị .

Như bạn có thể nhận thấy, pathMatch: fullcấu hình về cơ bản nói lên điều này:

Bỏ qua các con tôi và chỉ phù hợp với tôi. Nếu tôi không thể tự đối sánh tất cả các phân đoạn URL còn lại , thì hãy tiếp tục.

Chuyển hướng

Bất kỳ URL Routenào đã xác định a redirectTosẽ được đối sánh với URL mục tiêu theo các nguyên tắc tương tự. Sự khác biệt duy nhất ở đây là chuyển hướng được áp dụng ngay khi một phân đoạn khớp . Điều này có nghĩa là nếu một tuyến đường chuyển hướng đang sử dụng prefixchiến lược mặc định , một phần phù hợp là đủ để gây ra chuyển hướng . Đây là một ví dụ điển hình:

const routes: Routes = [
  {
    path: 'not-found',
    component: NotFoundComponent,
  },
  {
    path: 'users',
    redirectTo: 'not-found',
  },
  {
    path: 'users/:userID',
    children: [
      {
        path: 'comments',
        component: UserCommentsComponent,
      },
      {
        path: 'articles',
        component: UserArticlesComponent,
      },
    ],
  },
];

Đối với URL ban đầu của chúng tôi ( /users/james/articles), đây là những gì sẽ xảy ra:

  1. 'not-found' !== 'users' - bỏ qua nó.
  2. 'users' === 'users' - chúng ta có một trận đấu.
  3. Trận đấu này có một redirectTo: 'not-found', được áp dụng ngay lập tức .
  4. URL mục tiêu thay đổi thành not-found.
  5. Bộ định tuyến bắt đầu khớp lại và tìm thấy kết quả phù hợp not-foundngay lập tức. Ứng dụng kết xuất NotFoundComponent.

Bây giờ hãy xem xét điều gì sẽ xảy ra nếu userstuyến đường cũng có pathMatch: full:

const routes: Routes = [
  {
    path: 'not-found',
    component: NotFoundComponent,
  },
  {
    path: 'users',
    pathMatch: 'full',
    redirectTo: 'not-found',
  },
  {
    path: 'users/:userID',
    children: [
      {
        path: 'comments',
        component: UserCommentsComponent,
      },
      {
        path: 'articles',
        component: UserArticlesComponent,
      },
    ],
  },
];
  1. 'not-found' !== 'users' - bỏ qua nó.
  2. userssẽ khớp với phân đoạn đầu tiên của URL, nhưng cấu hình tuyến đường yêu cầu phải fullkhớp, do đó hãy bỏ qua nó.
  3. 'users/:userID'các trận đấu users/james. articlesvẫn chưa khớp nhưng tuyến này có trẻ em.
    • Chúng tôi tìm thấy một sự phù hợp cho articlestrẻ em. Toàn bộ URL hiện đã được khớp và ứng dụng hiển thị UserArticlesComponent.

Đường dẫn trống ( path: '')

Đường dẫn trống là một trường hợp hơi đặc biệt vì nó có thể khớp với bất kỳ phân đoạn nào mà không "tiêu thụ" nó (vì vậy đường dẫn con sẽ phải khớp lại phân đoạn đó). Hãy xem xét ví dụ này:

const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: 'users',
        component: BadUsersComponent,
      }
    ]
  },
  {
    path: 'users',
    component: GoodUsersComponent,
  },
];

Giả sử chúng tôi đang cố gắng truy cập /users:

  • path: ''sẽ luôn khớp, do đó tuyến đường khớp. Tuy nhiên, toàn bộ URL chưa được khớp - chúng tôi vẫn cần phải khớp users!
  • Chúng tôi có thể thấy rằng có một phần tử con users, khớp với phân đoạn còn lại (và duy nhất!) Và chúng tôi có một kết quả phù hợp đầy đủ. Ứng dụng kết xuất BadUsersComponent.

Bây giờ trở lại câu hỏi ban đầu

OP đã sử dụng cấu hình bộ định tuyến này:

const routes: Routes = [
  {
    path: 'welcome',
    component: WelcomeComponent,
  },
  {
    path: '',
    redirectTo: 'welcome',
    pathMatch: 'full',
  },
  {
    path: '**',
    redirectTo: 'welcome',
    pathMatch: 'full',
  },
];

Nếu chúng tôi đang điều hướng đến URL gốc ( /), đây là cách bộ định tuyến sẽ giải quyết điều đó:

  1. welcome không khớp với một phân đoạn trống, vì vậy hãy bỏ qua nó.
  2. path: ''khớp với phân đoạn trống. Nó có một pathMatch: 'full', điều này cũng hài lòng vì chúng tôi đã khớp toàn bộ URL (nó có một phân đoạn trống).
  3. Chuyển hướng welcomesẽ xảy ra và ứng dụng hiển thị WelcomeComponent.

Nếu không có thì pathMatch: 'full'sao?

Trên thực tế, người ta sẽ mong đợi toàn bộ sự việc sẽ hoạt động giống hệt nhau. Tuy nhiên, Angular ngăn chặn một cách rõ ràng cấu hình như vậy ( { path: '', redirectTo: 'welcome' }) vì nếu bạn đặt điều này Routeở trên welcome, về mặt lý thuyết nó sẽ tạo ra một vòng chuyển hướng vô tận. Vì vậy, Angular chỉ tạo ra một lỗi , đó là lý do tại sao ứng dụng sẽ không hoạt động! ( https://angular.io/api/router/Route#pathMatch )

Điều này thực sự không có quá nhiều ý nghĩa vì Angular đã triển khai một biện pháp bảo vệ chống lại các chuyển hướng vô tận - nó chỉ chạy một chuyển hướng duy nhất cho mỗi cấp định tuyến.

Về path: '**'thì sao?

path: '**'sẽ khớp hoàn toàn với bất kỳ thứ gì ( af/frewf/321532152/fsalà đối sánh) có hoặc không có a pathMatch: 'full', vì vậy không có ích gì khi sử dụng tùy chọn cấu hình này.

Ngoài ra, vì nó khớp với mọi thứ, nên đường dẫn gốc cũng được bao gồm, điều này làm cho { path: '', redirectTo: 'welcome' }thiết lập này trở nên thừa.

Thật thú vị, nó hoàn toàn ổn khi có cấu hình này:

const routes: Routes = [
  {
    path: '**',
    redirectTo: 'welcome'
  },
  {
    path: 'welcome',
    component: WelcomeComponent,
  },
];

Nếu chúng tôi điều hướng đến /welcome, path: '**'sẽ là một trận đấu và chuyển hướng để chào đón sẽ xảy ra. Điều này sẽ bắt đầu một vòng chuyển hướng vô tận nhưng Angular dừng điều đó ngay lập tức và toàn bộ hoạt động tốt.


3

Chiến lược đối sánh đường dẫn, một trong các 'tiền tố' hoặc 'đầy đủ'. Mặc định là 'tiền tố'.

Theo mặc định, bộ định tuyến sẽ kiểm tra các phần tử URL từ bên trái để xem liệu URL có khớp với một đường dẫn nhất định hay không và dừng lại khi có sự trùng khớp. Ví dụ: '/ team / 11 / user' đối sánh với 'team /: id'.

Chiến lược đối sánh đường dẫn 'đầy đủ' đối sánh với toàn bộ URL. Điều quan trọng là phải làm điều này khi chuyển hướng các tuyến đường vắng. Mặt khác, bởi vì một đường dẫn trống là tiền tố của bất kỳ URL nào, bộ định tuyến sẽ áp dụng chuyển hướng ngay cả khi điều hướng đến đích chuyển hướng, tạo ra một vòng lặp vô tận.

Nguồn: https://angular.io/api/router/Route#properties

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.