Angular — маршруты не работают — ошибка: NG04002: невозможно сопоставить ни один маршрут. URL-сегмент

Извините за мой плохой английский :/ Я пытаюсь создать простое приложение интернет-магазина с помощью Angular, но пока я пытаюсь получить доступ к двум маршрутам (домашний и «carrinho» [корзина по-португальски]), выдает ошибку: «Ошибка: NG04002: невозможно сопоставить ни один маршруты. URL-сегмент», и браузер перенаправляет на localhost:4200, а не на желаемый маршрут. Localhost:4200/carrinho должен показывать сообщение «carrinhoworks!». предложение, просто чтобы убедиться, что оно работает, но вместо этого у меня появляется ошибка, и меня перенаправляет на localhost: 4200, то же самое для дома. Итак, любой из этих двух работает. В эти дни я сталкиваюсь с плохими вещами, поэтому мое внимание, возможно, что-то проигнорировало. Я пытался найти то, что могло быть не так, и исправить это, даже посетил несколько тем здесь, посвященных переполнению стека, но не смог.

app-routing-module.ts — папка (src/app)

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CarrinhoComponent } from './pages/carrinho/carrinho.component'
import { HomeComponent } from './pages/home/home.component';

const routes: Routes = [
  {
    path: 'home',
    component: HomeComponent,
  },
  {
    path: 'carrinho',
    component: CarrinhoComponent,
  },
  { path: '', redirectTo: '/home', pathMatch: 'full' },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

app-module.ts — папка (src/app)

import { NgModule } from '@angular/core';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatGridListModule } from '@angular/material/grid-list';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { MatMenuModule } from '@angular/material/menu';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatTreeModule } from '@angular/material/tree';
import { MatListModule } from '@angular/material/list';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatTableModule } from '@angular/material/table';
import { MatBadgeModule } from '@angular/material/badge';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app.component';
import { HeaderComponent } from './components/header/header.component';
import { HomeComponent } from './pages/home/home.component';
import { ProductsHeaderComponent } from './pages/home/components/products-header/products-header.component';
import { FiltersComponent } from './pages/home/components/filters/filters.component';
import { CarrinhoComponent } from './pages/carrinho/carrinho.component';


@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    HeaderComponent,
    ProductsHeaderComponent,
    FiltersComponent,
    CarrinhoComponent,
  ],

  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatSidenavModule,
    MatGridListModule,
    MatMenuModule,
    MatButtonModule,
    MatCardModule,
    MatIconModule,
    MatExpansionModule,
    MatTreeModule,
    MatListModule,
    MatToolbarModule,
    MatTableModule,
    MatBadgeModule,
    MatSnackBarModule,
    HttpClientModule
  ],
  exports: [
    MatSidenavModule,
    MatGridListModule
  ]
})
export class AppModule { }

домашний-компонент.ts

import { Component } from '@angular/core';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatGridListModule } from '@angular/material/grid-list';
import { ProductsHeaderComponent } from './components/products-header/products-header.component';
import { FiltersComponent } from './components/filters/filters.component';
import { ProductBoxComponent } from './components/product-box/product-box.component';

const ROWS_HEIGHT: { [id: number]: number } = { 1: 400, 3: 335, 4: 350 };

@Component({
  selector: 'app-home',
  standalone: true,
  imports: [ProductBoxComponent, FiltersComponent, ProductsHeaderComponent, MatSidenavModule, MatGridListModule],
  templateUrl: './home.component.html',
  styleUrl: './home.component.css'
})
export class HomeComponent {
  cols = 3;

  rowHeight = ROWS_HEIGHT[this.cols];

  categoria: string | undefined;

  constructor(){

  }

  ngOnInit(): void {

  }

  onColumnsCountChange(numCols: number): void {
    this.cols = numCols;
    this.rowHeight=ROWS_HEIGHT[this.cols];
  }

  onShowCategoria(novaCategoria: string): void {
    this.categoria = novaCategoria;
  }
}

приложение-компонент.ts

import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { HeaderComponent } from './components/header/header.component';
import { HomeComponent } from './pages/home/home.component';
import { CarrinhoComponent } from './pages/carrinho/carrinho.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [HomeComponent, HeaderComponent, CarrinhoComponent, RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'loja';
}

приложение-компонент.html


      <app-header></app-header>
      <router-outlet></router-outlet>
      <app-home></app-home>

header-comComponent.html (с кнопкой, использующей routerLink для маршрута carrinho (корзины))

<mat-toolbar class = "mat-toolbar-custom max-w-7x1-mx-auto border-x justify-between">
  <a routerLink = "home">Conheça a Loja</a>
  <button mat-icon-button [matMenuTriggerFor] = "menu">
    <mat-icon
    [matBadge] = "1"
    [style.color] = "'rgb(22, 99, 115)'"
    >shopping_cart</mat-icon>
  </button>
  <mat-menu #menu = "matMenu">
    <div class = "p-3 divide-y divide-solid">
      <div class = "pb-3 flex justify-between">
      <span class = "mr-16">1 items</span>
      <br>
      <a routerLink = "carrinho">Consultar Carrinho</a>
    </div>
    <div class = "p-4">
      <div class = "flex justify-between font-light mb2">
      Keyboard x1
      <span class = "font-bold">{{ '150' | currency: 'BRL' }}</span>
      </div>
      <div class = "flex justify-between font-light mb2">
        Keyboard x1
        <span class = "font-bold">{{ '150' | currency: 'BRL' }}</span>
      </div>
      <div class  = "flex justify-between py-3 font-light">
        Total:
        <span class = "font-bold">{{ '300' | currency: 'BRL'}}</span>
      </div>
      <div class = "pt-3 flex justify-between">
        <button class = "bg-text-white-rounded-full w-10 h-10">
          <mat-icon>remove_shopping_cart</mat-icon>
        </button>
        <button routerLink = "carrinho" class = "bg-text-white-rounded-full w-10 h-10">
          <mat-icon>remove_shopping_cart</mat-icon>
        </button>
      </div>
    </div>
    </div>
  </mat-menu>
</mat-toolbar>

carrinho.comComponent.html

<p>carrinho works!</p>

Я ожидал, что на самом деле произойдет перенаправление на localhost: 4200/home (показывающее, что находится внутри домашнего компонента) и localhost: 4200/carrinho (показывающее, что находится внутри компонента carrinho, который «carrinho работает» только в целях тестирования).

Обновление: только что добавил /home в index.html, и теперь домашний маршрут работает, но Карринью по-прежнему не работает :(

Обновление 2: я также добавил маршруты в app-routes.ts, и кажется, что /carrinho теперь работает, но также загружает компоненты домашней страницы, а не только те, что из маршрута carrinho, поэтому они отображаются неправильно. То же самое и с домашней страницей.. (эта страница была прямо перед тем, как на картинке 2, без «работ Карринью»)

https://i.sstatic.net/4jFcW.png
https://i.sstatic.net/VLtoZ.png
https://i.sstatic.net/rGDKx.png

Решено: наконец-то решена проблема с загрузкой компонентов маршрута carrinho из других маршрутов с использованием ChangeDetectionStrategy Alpine, использованного в его ответе!

Не могли бы вы поделиться ссылкой на роутер?

Alpine A110R 13.04.2024 20:17

Конечно :), обновил пост новой информацией. Но, как правило, до сих пор я использовал только одну ссылку routerLink в компоненте заголовка, для кнопки и для ссылки «Консультант Карриньо». Только что увидел видео, и я действовал практически по той же логике, что и он, он просто набирал маршрут в браузере и все работало, но не у меня :(

Igor C 13.04.2024 20:48
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
2
1 478
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно изменить app.comComponent.html:

  <app-header></app-header>
  <router-outlet></router-outlet>
  <app-home></app-home>

К

  <app-header></app-header>
  <router-outlet></router-outlet>

Заголовок содержит routerLink компонента, поэтому он отображается с router-outlet.

Эта конфигурация маршрута создает статическую ссылку на маршрут:

// заголовок приложения

<a routerLink = "/home">Home component </a>
<a routerLink = "/carrinho">Carrinho component</a>

// конфигурация маршрута

const routes: Routes = [
  {
    path: 'home',
    component: HomeComponent,
  },
  {
    path: 'carrinho',
    component: CarrinhoComponent,
  },
  { path: '', redirectTo: '/home', pathMatch: 'full' },
];

Демо-версия Stackblitz

Примечание:

  • Если первый сегмент начинается с /, маршрутизатор ищет маршрут от корня приложения.
  • Если первый сегмент начинается с ./ или не начинается с косой черты, маршрутизатор просматривает дочерние элементы текущего активированного маршрута.
  • Если первый сегмент начинается с ../, маршрутизатор поднимается на один уровень выше в дереве маршрутов.

Спасибо за внимание. Итак, если я наберу localhost: 4200/home или carrinho в браузере, чтобы действительно сопоставить маршруты, мне нужно добавить косую черту в routerLinks в компоненте заголовка? Пробовал это, но все равно не работает. Независимо от того, какие изменения я вношу в ссылки маршрутизатора, URL-адрес по-прежнему не совпадает и не перенаправляется на них :(

Igor C 13.04.2024 21:47

у вас есть тег <base href = "/"> в index.html?

Alpine A110R 13.04.2024 22:03

Да, попробуйте использовать косую черту, например: <a routerLink = "/home">Conheça a Loja</a>

Alpine A110R 13.04.2024 22:08

Добавлен <base href = "/"> для дома в index.html, и теперь маршрут домой работает! Спасибо, но Карриньо остался прежним :(

Igor C 13.04.2024 22:50

вы поставили косую черту для <a routerLink = "/carrinho">Консультант Карринью</a>

Alpine A110R 13.04.2024 23:04

Сделал, но все равно не работает ;(

Igor C 13.04.2024 23:25

Привет, Alpine, есть некоторые обновления, отредактировал основной пост. Карриньо, кажется, соответствует, но отображается неправильно, то же самое сейчас для дома.

Igor C 14.04.2024 19:49

@IgorC Я не понимаю, зачем вам добавлять /home в index.html? Не могли бы вы поделиться текущим index.html?

Alpine A110R 14.04.2024 21:35

Ваш снимок не отображается.

Alpine A110R 14.04.2024 21:39

Пока не могу загрузить изображения сюда:/ Но я думаю, что копирование и вставка в строку URL-адреса сработают, если есть какой-либо другой способ отправить их сюда. Но обычно, когда я получаю доступ к маршруту carrinho, он загружает оба компонента home и carrinho. И дом как будто некорректно отображается (кнопки не на своих местах, на экране не появляются значки, вместо них появляются надписи)

Igor C 14.04.2024 23:34

Исправил проблему с иконками и кнопками. Но проблема с загрузкой компонентов дома по маршруту Карринью остается прежней :(

Igor C 14.04.2024 23:44

@IgorC проверьте демо stackblitz

Alpine A110R 15.04.2024 11:50

Огромное спасибо Альпине! Что мне помогло, так это добавить ChangeDetection: ChangeDetectionStrategy.OnPush в header.comComponent.html, и теперь маршрут carrinho показывает только «carrinho работает». Надеюсь, мне больше не придется задавать вопросы, пока я не закончу этот небольшой проект xD. Спасибо за внимание!

Igor C 15.04.2024 18:29

Другие вопросы по теме