#angular #angular-routing
Вопрос:
В моем приложении есть много компонентов, которые почти одинаковы. Каждый компонент содержит диаграмму с аналогичными параметрами и различными рядами данных. Вся выборка и обработка данных происходит в сервисе.
Мне пришла в голову идея, что мне не нужно так много почти одинаковых компонентов, и я просто передам опции и серии через сервис. Это уменьшит количество шаблонов. Но является ли это хорошей практикой? Лучше ли иметь 10 служб и 10 компонентов или 10 служб и 1 компонент, которые изменят обслуживание при изменении маршрута?
К тому же это всего лишь теория. Я пытался это сделать, но застрял на том, как предоставить другую услугу после изменения маршрута, а затем повторно запустить компонент. Не смог найти никакой информации об этом, поэтому любой совет был бы очень полезен.
Я воссоздал эту проблему на StackBlitz.
Ответ №1:
Вы можете использовать абстрактные классы, инъекции зависимостей и заводы, поясню: во-первых, вы можете создать Service
абстрактный класс, который будет модель для конкретных служб и вводят маркер в свой компонент, а затем использовать serviceFactory
для введения конкретный класс обслуживания в компоненте в зависимости от выполнения параметров (например, путь следования к примеру)
Я сделал это в этом стакблитце
Вы увидите, что при переходе к /шаблону используется сервис1 и отображается число 1.
И при переходе к /шаблону2 используется сервис2 и отображается число 2
Дайте мне знать, если у вас возникнут вопросы.
Комментарии:
1. Это то, что я искал, но есть ли способ уничтожить предыдущую службу при изменении маршрута?
2. @abellay Я думаю, что они удаляются напрямую, если вы предоставляете свои услуги в самом компоненте, нет? Проверьте еще раз stackblitz, я добавил метод приращения, и вы можете увеличить, а затем изменить шаблон, временный параметр будет повторно инициализирован
Ответ №2:
ДА. Хорошей практикой является наличие 1 компонента и 10 услуг
Если содержимое всех компонентов почти одинаково, вы можете повторно использовать один и тот же компонент для всех ваших маршрутов. лучший подход-использовать 1 компонент и 10 сервисов.
Вы можете решить, какие службы использовать для извлечения данных, используя условия, использующие данные, переданные компоненту в качестве входных данных, или вы можете использовать другую службу для хранения текущих данных и рядов.
Ответ №3:
Вы можете использовать распознаватели для отправки данных на маршрут. Я немного изменил код, чтобы вы могли указать, какая служба может быть отправлена по какому маршруту. Я не говорю, что это лучший способ, но вы можете попробовать это. Вы даже можете поддерживать собственное хранилище служб вместо создания экземпляров каждый раз, как это было сделано в serviceResolvers.ts
//// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import {
Service1Resolver,
Service2Resolver,
} from '../component/serviceResolvers';
import { TemplateComponent } from '../component/template.component';
import { AppComponent } from './app.component';
const routes: Routes = [
{
path: '',
redirectTo: 'home',
pathMatch: 'full',
},
{
path: 'template',
component: TemplateComponent,
resolve: {
service: Service1Resolver, // Customize your service
},
},
{
path: 'template2',
component: TemplateComponent,
resolve: {
service: Service2Resolver,
},
},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [Service1Resolver, Service2Resolver],
})
export class AppRoutingModule {}
/// serviceResolvers.ts
import { Injectable } from '@angular/core';
import {
ActivatedRouteSnapshot,
Resolve,
RouterStateSnapshot,
} from '@angular/router';
import { Service1Service } from './service1.service';
import { Service2Service } from './service2.service';
@Injectable()
export class Service1Resolver implements Resolve<any> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return new Service1Service();
}
}
@Injectable()
export class Service2Resolver implements Resolve<any> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return new Service2Service();
}
}
Ответ №4:
Вы должны передать chartId в качестве параметра маршрута. Таким образом, ваша конфигурация маршрутизации будет намного проще и чище:
{
path: 'template/:chartId',
component: TemplateComponent,
},
Затем в разделе TemplateComponent
вы подписываетесь на ActivatedRoute
обнаружение изменений параметров маршрута:
constructor(
private _service1: Service1Service,
private _service2: Service2Service,
private route: ActivatedRoute
) {}
ngOnInit(): void {
this.route.params.subscribe((params) => {
const selectedChartId = params['chartId'];
if (selectedChartId === 1) {
this.service = this._service1;
} else {
this.service = this._service2;
}
this.number = this.service.temp;
});
}
Проверьте этот стекблитц, который я создал на основе вашего кода: https://stackblitz.com/edit/angular-ivy-m3f5do?file=src/component/template.component.ts
Измените диаграмму с 1 на 2, чтобы она работала: https://angular-ivy-m3f5do.stackblitz.io/template/1