Как обрабатывать изменения маршрутизации Angular 2 (7) без рефакторинга?

#angular #angular7

#angular #angular7

Вопрос:

Прямо сейчас рекомендуемая маршрутизация — иметь массив маршрутов, который выглядел бы примерно так:

 const appRoutes: Routes = [
    { path: '', redirectTo: '/login', pathMatch: 'full' },
    { path: 'page1', component: Page1Component },  // can't use RouterStringService here I don't think...
    { path: 'page2', component: Page2Component }
]
@NgModule({...})
export class AppRouting Module {}
  

Это все хорошо и отлажено. Мы можем использовать это для навигации:

  • ts-файлы — router.navigate(['/page1'])
  • html-файлы — [routerLink]="/page1"

Прохладный. Это отлично работает. Однако, что произойдет, если нам нужно изменить page1 на home-feed (или что-либо, что не является page1 )? Рефакторинг строковых литералов — это пустяк, вызывающий проблемы (особенно в html). Мы можем использовать перенаправления следующим образом:

 // changes to above code block
{ path: 'page1', redirectTo: 'new-page1' },
{ path: 'new-page1', component NewPage1Component },
  

Но это просто добавляет умственных затрат на запоминание перенаправлений, потому что другие ссылки на код все еще потенциально будут router.navigate(['/page1']) .

Мы также можем использовать сервис, который импортируется почти везде. Это (если я не ошибаюсь) было бы невозможно использовать внутри appRoutes , потому что это объявлено вне модуля? (это отмечено в первом блоке кода)

 export class RouterStringService {
    static page1: string = '/page1'
    static page2: string = '/page2

    // put string builders here too for things like /pageX/:id

    constructor() {}
}
  

Как вы, ребята, справляетесь с этим? Я знаю, что рефакторинг не идеален, но бывают случаи, когда это должно произойти. Больше всего меня беспокоит отсутствие маршрутизации, потому что angular 7 использует строковые литералы. Используете ли вы тестирование e2e для обнаружения этого или можете исправить это программно?

Ответ №1:

Я также стремлюсь избегать строковых литералов в коде, насколько это возможно по причинам, которые вы упомянули. Хорошей идеей является наличие файлов конфигурации (например, environment.ts), которые служат справочным словарем для разных URL-адресов.

Если вам нужно изменить точные строковые литералы, вы можете сделать это в одном месте.

На эти объекты конфигурации можно ссылаться из TS-файлов или также из HTML-шаблонов, если вы экспортируете их в шаблон в соответствующем компоненте.

Например: urls.ts файл где-нибудь в ресурсах или любой другой папке:

 export const AppUrls = {
    base: "...",
    login: "...",
    ...
} 
  

в файлах ts:

    import {AppUrls} from '..../urls.ts';

    const appRoutes: Routes = [
        { path: '', redirectTo: AppUrls.login, pathMatch: 'full' },
  

в шаблонах сначала вы экспортируете его:

 import {AppUrls} from '..../urls.ts';

@Component({
  selector: '...
})
export class SomeComponent implements OnInit {

  AppUrls = AppUrls;
  

и в html:

 [routerLink]="{{AppUrls.login}}"
  

Кроме того, router.navigate(['/page1']) не требуется косая черта, и вы можете разделять разные URL-адреса как записи массива: router.navigate(['firstpart', 'secondpart']) -> это приведет вас к /firstpart/secondpart

Комментарии:

1. В этом примере AppUrls.base = '/' , верно? Тогда, если вы используете несколько словарей ( AppUrls.base = '/' , UserUrls.base = '/users' , CameraUrls.base = '/camera' ), все, что вам нужно сделать, это соответствующим образом настроить базы, верно? Я также не знал, router.navigate что поддерживаются массивы, спасибо за этот лакомый кусочек.

2. это был просто какой-то случайный заполнитель, который я написал. baseUrl должен быть определен в index.html с помощью тега ` <base href=»/»>`, или вы можете задать его динамическим способом, предоставив его в providers массиве, как это описано здесь: projectcodify.com/angular-set-base-url-dynamically