Що стосується Angular, що таке "pathmatch: full" і який ефект він має?


101

Тут він використовує pathmatch як повний, і коли я видаляю цей pathmatch, він навіть не завантажує програму або не запускає проект

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 { }

Відповіді:


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

Випадок 1 pathMatch:'full' : У цьому випадку, коли додаток запускається на localhost:4200(або якомусь сервері), сторінкою за замовчуванням буде екран вітання, оскільки URL-адреса будеhttps://localhost:4200/

Якщо https://localhost:4200/gibberishце призведе до переходу на екран pageNotFound через path:'**'підстановочний знак

Випадок 2 pathMatch:'prefix' :

Якщо маршрути є { path: '', redirectTo: 'welcome', pathMatch: 'prefix' }, зараз це ніколи не дійде до шаблону підстановки, оскільки кожна URL-адреса буде відповідати path:''визначеному.


привіт, дякую за чітке пояснення цього прикладу, але чи можете ви навести в якості іншого прикладу інший тип маршрутів, щоб зробити це повністю зрозумілим, будь ласка? (наприклад, на прикладі з дитячими маршрутами тощо). спасибі
sohaieb

дуже гарне пояснення, сер, але чи можете ви сказати мені, як налаштувати 2 різні макети. як внутрішній макет та зовнішній макет>
Kapil Soni

87

pathMatch = 'full' призводить до потрапляння маршруту, коли решта, не збігаються сегменти URL-адреси, відповідають шляху префіксу

pathMatch = 'prefix'повідомляє маршрутизатору, щоб він відповідав маршруту перенаправлення, коли решта URL-адрес починається із шляху префіксу маршруту перенаправлення.

Посилання: https://angular.io/guide/router#set-up-redirects

pathMatch: 'full' означає, що весь шлях URL повинен збігатися і використовуватися алгоритмом узгодження маршруту.

pathMatch: 'prefix' означає, що обраний перший маршрут, де шлях відповідає початку URL-адреси, але потім алгоритм узгодження маршрутів продовжує пошук відповідних дочірніх маршрутів, де решта URL-адрес відповідає.


24

Хоча технічно правильні, інші відповіді допомогли б пояснити відповідність URL-адреси маршруту Angular. Я не думаю, що ви можете повністю (вибачте за каламбур) зрозуміти, що pathMatch: fullробити, якщо ви не знаєте, як працює маршрутизатор.


Давайте спершу визначимося з кількома основними речами. Ми будемо використовувати цю адресу в якості прикладу: /users/james/articles?from=134#section.

  1. Це може бути очевидно, але давайте спочатку зазначимо, що параметри запиту ( ?from=134) та фрагменти ( #section) не відіграють жодної ролі у зіставленні шляхів . Важлива лише основна URL-адреса ( /users/james/articles).

  2. Angular розбиває URL-адреси на сегменти . Сегменти /users/james/articles, звичайно, users, jamesі articles.

  3. Конфігурація маршрутизатора - це деревоподібна структура з одним кореневим вузлом. Кожен Routeоб'єкт - це вузол, який може мати childrenвузли, які, в свою чергу, можуть мати інші childrenабо бути листовими вузлами.

Мета маршрутизатора - знайти гілку конфігурації маршрутизатора , починаючи з кореневого вузла, яка точно відповідала б усім (!!!) сегментам URL-адреси. Це надзвичайно важливо! Якщо не Кутовий годі й шукати конфігурації маршруту гілки , яка може відповідати всьому URL - не більше і не менше - це не не зробить нічого .

Наприклад, якщо ваша цільова URL-адреса є, /a/b/cале маршрутизатор може збігатися лише з /a/bабо /a/b/c/d, тоді збігу немає, і програма нічого не відобразить.

Нарешті, маршрути з redirectToповодяться дещо інакше, ніж звичайні маршрути, і мені здається, що вони були б єдиним місцем, де хтось справді хотів би використовувати pathMatch: full. Але до цього ми дійдемо пізніше.

prefixВідповідність шляху за замовчуванням ( )

Обґрунтування назви prefixполягає в тому, що така конфігурація маршруту перевірятиме, чи налаштований pathє префіксом до інших сегментів URL-адреси. Однак маршрутизатор може збігатися лише з повними сегментами , що робить це іменування трохи заплутаним.

У будь-якому випадку, припустимо, це наша конфігурація маршрутизатора кореневого рівня:

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

Зауважте, що кожен окремий Routeоб’єкт тут використовує стратегію відповідності за замовчуванням, яка є prefix. Ця стратегія означає, що маршрутизатор перебирає все дерево конфігурації та намагається зіставити його з цільовим сегментом URL-адреси за сегментом, поки URL-адреса не буде повністю збігатися . Ось як це можна зробити для цього прикладу:

  1. Перебирайте кореневий масив, шукаючи точну відповідність для першого сегмента URL - users.
  2. 'products' !== 'users', тому пропустіть цю гілку. Зверніть увагу, що ми використовуємо перевірку на рівність, а не - .startsWith()або .includes()лише - збіги повного сегмента!
  3. :otherвідповідає будь-якому значенню, тому це збіг. Однак цільова URL-адреса ще не повністю узгоджена (нам все одно потрібно збігатись jamesі articles), тому маршрутизатор шукає дітей.
    • Єдина дитина :otherє tricks, що є !== 'james', отже, не збігом.
  4. Потім Angular повертається назад до кореневого масиву і продовжує звідти.
  5. 'user' !== 'users, пропустити гілку.
  6. 'users' === 'users- сегмент відповідає. Однак це ще не повний збіг, тому нам потрібно шукати дітей (те саме, що на кроці 3).
    • 'permissions' !== 'james', пропустити це.
    • :userIDзбігається з чим завгодно, таким чином, ми маємо збіг для jamesсегменту. Однак це все ще не повний збіг, тому нам потрібно шукати дитину, яка б відповідала articles.
      1. Ми бачимо, що :userIDє дочірній маршрут articles, який дає нам повний збіг! Таким чином додаток відображається UserArticlesComponent.

Повна відповідність URL ( full)

Приклад 1

Уявіть собі, що usersоб'єкт конфігурації маршруту виглядав так:

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

Зверніть увагу на використання pathMatch: full. Якби це було так, кроки 1-5 були б однаковими, проте крок 6 були б іншими:

  1. 'users' !== 'users/james/articles- сегмент не відповідає, оскільки конфігурація шляху usersз pathMatch: fullне відповідає повній URL-адресі, яка є users/james/articles.
  2. Оскільки збігу немає, ми пропускаємо цю гілку.
  3. На цьому етапі ми досягли кінця конфігурації маршрутизатора, не знайшовши збігу. Програма нічого не робить .

Приклад 2

Що якби ми мали це замість цього:

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

users/:userIDpathMatch: fullлише із збігами, users/jamesтаким чином, це ще раз не збіг, і програма нічого не відображає.

Приклад 3

Давайте розглянемо це:

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

В цьому випадку:

  1. 'users' === 'users- сегмент відповідає, але james/articlesвсе ще залишається неперевершеним. Давайте шукати дітей.
    • 'permissions' !== 'james' - пропустити.
    • :userID'може відповідати лише одному сегменту, що було б james. Однак це pathMatch: fullмаршрут, і він повинен збігатися james/articles(вся залишилася URL-адреса). Він не в змозі цього зробити, і, отже, це не збіг (тому ми пропускаємо цю гілку)!
  2. Знову ж таки, нам не вдалося знайти відповідність для URL-адреси, і програма нічого не робить .

Як ви могли помітити, pathMatch: fullконфігурація в основному говорить про це:

Ігноруй своїх дітей і зрівняйся лише зі мною. Якщо мені не вдається зіставити всі інші сегменти URL-адреси, перейдіть далі.

Перенаправлення

Будь- Routeхто, хто визначив a, redirectToбуде зіставлений з цільовою URL-адресою за тими ж принципами. Єдина різниця тут полягає в тому, що переспрямування застосовується, як тільки сегмент збігається . Це означає, що якщо маршрут перенаправлення використовує prefixстратегію за замовчуванням , часткового збігу досить, щоб викликати переспрямування . Ось хороший приклад:

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

Для нашої початкової URL-адреси ( /users/james/articles) ось що трапиться:

  1. 'not-found' !== 'users' - пропустити це.
  2. 'users' === 'users' - у нас сірник.
  3. Цей збіг має a redirectTo: 'not-found', який застосовується негайно .
  4. Цільова URL-адреса змінюється на not-found.
  5. Маршрутизатор починає збіг знову і not-foundвідразу знаходить відповідність. Програма надає NotFoundComponent.

А тепер подумайте, що сталося б, якби usersмаршрут також мав 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' - пропустити це.
  2. usersвідповідав би першому сегменту URL-адреси, але конфігурація маршруту вимагає fullзбігу, таким чином пропустивши його.
  3. 'users/:userID'сірники users/james. articlesдосі не відповідає, але цей маршрут має дітей.
    • Ми знаходимо відповідність для articlesдітей. Тепер узгоджено всю URL-адресу, і програма відображається UserArticlesComponent.

Порожній шлях ( path: '')

Порожній шлях - це трохи особливий випадок, оскільки він може збігатися з будь-яким сегментом, не "споживаючи" його (тому його дітям доведеться збігатися з цим сегментом знову). Розглянемо цей приклад:

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

Скажімо, ми намагаємось отримати доступ /users:

  • path: ''завжди збігатиметься, отже, маршрут збігається. Однак не знайдено відповідності всій URL-адресі - нам все одно потрібно збігатися users!
  • Ми бачимо, що існує дочірній матеріал users, який відповідає решті (і єдиному!) Сегменту, і ми маємо повний збіг. Програма надає BadUsersComponent.

Повернемось до початкового питання

OP використовував таку конфігурацію маршрутизатора:

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

Якщо ми переходимо до кореневої URL-адреси ( /), ось як це може вирішити маршрутизатор:

  1. welcome не відповідає порожньому сегменту, тому пропустіть його.
  2. path: ''відповідає порожньому сегменту. Він має a pathMatch: 'full', що також задовольняється, оскільки ми зіставили цілу URL-адресу (вона мала один порожній сегмент).
  3. Відбувається переспрямування, welcomeі додаток відображається WelcomeComponent.

Що робити , якщо не було pathMatch: 'full'?

Власне, можна було б очікувати, що вся справа поводиться точно так само. Однак Angular явно запобігає такій конфігурації ( { path: '', redirectTo: 'welcome' }), оскільки якщо ви покладете це Routeвище welcome, це теоретично створить нескінченний цикл редиректів. Отже, Angular просто видає помилку , ось чому додаток взагалі не буде працювати! ( https://angular.io/api/router/Route#pathMatch )

Це насправді не має надто великого сенсу, оскільки Angular запровадив захист від нескінченних переспрямувань - він виконує лише одне перенаправлення на рівень маршрутизації.

Що про path: '**'?

path: '**'буде відповідати абсолютно будь-чому ( af/frewf/321532152/fsaце збіг) з або без pathMatch: 'full', тому немає сенсу використовувати цю опцію конфігурації.

Крім того, оскільки він відповідає усьому, також включений кореневий шлях, що робить { path: '', redirectTo: 'welcome' }зайвим у цьому налаштуванні.

Як не дивно, цілком нормально мати таку конфігурацію:

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

Якщо ми перейдемо до /welcome, path: '**'буде матч і відбудеться переадресація на привітання. Це повинно розпочати нескінченний цикл переспрямувань, але Angular зупиняється це негайно, і все це працює нормально.


3

Стратегія зіставлення шляхів, одна з "префікса" або "повної". За замовчуванням використовується "префікс".

За замовчуванням маршрутизатор перевіряє елементи URL-ліворуч, щоб перевірити, чи відповідає URL-адреса заданому шляху, і зупиняється, коли є збіг. Наприклад, '/ team / 11 / user' збігається з 'team /: id'.

Стратегія збігу шляхів "повна" відповідає всій URL-адресі. Це важливо робити під час перенаправлення порожніх шляхів. В іншому випадку, оскільки порожній шлях є префіксом будь-якої URL-адреси, маршрутизатор застосовуватиме переспрямування навіть під час навігації до пункту переспрямування, створюючи нескінченний цикл.

Джерело: https://angular.io/api/router/Route#properties

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.