Как стать автором
Обновить

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

Дмитрий, спасибо за статью!

Мы пару лет назад пришли точно к такому же решению, но вот есть один момент, который отличается и хочу обратить на него ваше внимание.

tuiGenerateDialogableRoute - принимает только два нужных параметра — компонент и путь.

Не уверен, что этот подход хорош, т.к. на самом деле, существует еще множество параметров, которые нужны. Например Resolver, либо же guard.

У нас хелпер принимает интерфейс Route из angular/route, тем самым мы не ограничиваем разработчика своими обертками, а лишь помогаем ему в реализации его планов.

Что думаете?



Здорово, что пришли к одинаковому решению!

В статье я чуть упростил интерфейс функции, у нас он еще принимает конфиг по диалогу.
Но вот резолверы и гварды, к сожалению, нет. Предложение 100% валидное. Я добавлю поддержку интерфейса Route в следующей версии.

Спасибо за наводку!

Можно ведь еще проще, через именованые роуты делать
Для моих задач никаких минусов в этой реализации небыло
Навигация отдельная, можно с любого места открыть любой диалог, вынести это в ленивый модуль
Возможно только может смущать нестандартный вид url
Что-то такого вида /home(dialog:login)
При том не нужны никакие костыли в виде backUrl и т.п.

Базовый пример

app.component.html

<router-outlet></router-outlet> <!-- Для основных страниц -->
<router-outlet name="dialog"></router-outlet> <!-- Для диалогов -->


app.routing.ts

// Пример роутинга
RouterModule.forRoot([
  {
    path: "home",
    component: HomeComponent,
  },
  {
    path: "login",
    outlet: "dialog",
    component: LoginComponent,
  },
  {
    path: "registration",
    outlet: "dialog",
    component: RegistrationComponent,
  },
]),

// Пример навигации
// Это не влияет на основной роутинг
return this.router.navigate([{
  outlets : {dialog : ['/login']}
}]);

// Кажется даже так можно, т.е. роутер аутлетами можно управлять по отдельности
// И они не влияют друг на друга
return this.router.navigate(['/home', {
  outlets : {dialog : ['/login']}
}]);

// А если вы так сделаете, а при этом у вас открыт диалог
// то основная страница поменяется, а диалог все так де висеть будет
return this.router.navigate(['/home', {
  outlets : {dialog : ['/login']}
}]);

Хорошая альтернатива. Я рассматривал такой вариант, но решил сделать как в статье.

Тут остается такая же проблема со сменой урла с /home(dialog:login) на /home при закрытии диалога. Ее в любом случае надо как-то решать. Было бы интересно узнать ваш способ. Иначе, если не менять урл, то при закрытии диалога урл остается таким же /home(dialog:login) и при перезагрузке страницы будет открыт диалог. А это не совсем то, что ожидает пользователь.

При том не нужны никакие костыли в виде backUrl и т.п.

вычисление backUrl - это детали реализации, которые не нужны при конфигурировании роутинга

В итоге конфиг роутера получается таким(реальный пример)

// роутинг модуль
const routes: Routes = [
  {
    path: 'page',
	component: PageComponent,
	children: [
  	  tuiGenerateDialogableRoute(DialogContentComponent, 'path/to/dialog')
	]
  }
]

Программисту, кто пишет такую конфигурацию, не надо задумываться о возвращении назад.

В вашем варианте через именованные аутлеты удобно, что можно в корне приложения один раз разместить <router-outlet name="dialog"> и не добавлять в каждую страницу — это плюс!

this.router.navigate([{ outlets : {dialog : null} }]);

Этот код закрывает диалог и не влияет на основной роутинг
т.е. в итоге от /home(dialog:login) остается /home

По началу кажется неплохой идеей, но потом не очень - слишком много приседаний надо, еще это загрязняет историю. Можно передать любой параметр в урле и потом в самом компоненте решить - надо что-то делать или нет, вместо path/to/dialog - ?dialog. Сам диалог оформить в виде сервиса с подпиской на роут параметры, ngOnInit - не нужен, можно прямо в конструкторе. Более того, теперь c hostDirectives можно не инжектить явно ничего в сам компонент.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий