1

I want to make several different module layouts

For example, I made one separate layout and named it user. Now, I have two layouts, one main, root layout and user layout.

In the main layout, I made a button that leads to the user component. And in the user layout, I made a button that leads to the main component.

The task before me is to make it so that when the button is pressed, the component from which I leave disappears. What I mean is that if I'm in the main root component and I press the "user" button which leads to the /user page, then after clicking I should go to the /user page and the main component should disappear. Or if I am in the /user component and press the "home" button that leads to the /home page, then after clicking I should go to the main /home and the /user component should disappear.

I implemented this using a service.

After I did, I noticed that if I go to the /user page and try to refresh it, then at some point, for a fraction of a second, I notice the main component. He appears and disappears. This happens very quickly and at the same time - it is very noticeable. It worries me, I don't know how to get rid of this defect. Please tell me how to get rid of this problem?

AppComponent

    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnDestroy {

      show: boolean = true;

      subscription: Subscription;
      constructor(private showContentService: ShowContentService) {
        this.subscription = showContentService.contentHome.subscribe(value => {
          this.show = value;
        });
      }

      hideContent() {
        this.show = false;
      }


      ngOnDestroy() {
        // Prevent memory leak when component is destroyed
        this.subscription.unsubscribe();
      }

    }

app.component.html

    <ng-container *ngIf="show">

      <p>Main page</p>

      <button (click)="hideContent()" routerLink="/user">User</button>

    </ng-container>


    <router-outlet></router-outlet>

AppRoutingModule

    const routes: Routes = [

      { path: 'user', loadChildren: () => import('./user/user.module').then(m => m.UserModule) }

    ];

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

ShowContentService

    @Injectable({
      providedIn: 'root'
    })
    export class ShowContentService {

      // Observable string sources
      private showContent = new Subject<boolean>();

      // Observable String Streams
      contentHome = this.showContent.asObservable();

      showContentHome(showContent: boolean) {
        this.showContent.next(showContent);
      }

    }

UserComponent

    export class UserComponent {

      constructor(private showContentService: ShowContentService) {
        this.showContentService.showContentHome(false);
      }

      showContentHome() {
        this.showContentService.showContentHome(true);
      }

      ngOnInit(): void {
      }

    }

user.component.html

    <p>User page</p>
    <button (click)="showContentHome()" routerLink="/">Home</button>

UserRoutingModule

    const routes: Routes = [

      { path: '', component: UserComponent }

    ];

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

https://github.com/MyTestPerson/Multi-Layout

enter image description here

MarieSpeak
  • 57
  • 7
  • You should be using routes to navigate, not a custom service. – Chris Hamilton Jul 30 '22 at 18:29
  • @Chris Hamilton I am using routes. Or not noticeable? – MarieSpeak Jul 30 '22 at 18:31
  • Yes, but you're only using it for the user component - not this other component that's giving you issues. See here: https://stackoverflow.com/questions/46527826/best-method-to-set-different-layout-for-different-pages-in-angular-4. The reason you see the flash is because you have `show` default to true, you could default this to false instead, but that link will show you the proper way to implement layouts for different routes. You can have a separate route for each layout. – Chris Hamilton Jul 30 '22 at 18:42
  • Does this answer your question? [Best method to set different layout for different pages in angular 4](https://stackoverflow.com/questions/46527826/best-method-to-set-different-layout-for-different-pages-in-angular-4) – Chris Hamilton Jul 30 '22 at 18:51

1 Answers1

1

A possible solution is to use multiple <router-outlet> elements. You can have a router outlet for each module.

The way I would structure it is to have your main app be just a router-outlet element in the template. I would then create two separate modules, one for main, and one for user. Each of these modules would contain their own router outlet and their own layout components which would render in the root apps router outlet.

app-routing.module.ts

const routes: Routes = [
  {
    path: '',
    loadChildren: () => import('./main/main.module').then((m) => m.MainModule),
  },
  {
    path: 'user',
    loadChildren: () => import('./user/user.module').then((m) => m.UserModule),
  },
];

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

app.component.html

<router-outlet></router-outlet>

main-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { MainLayoutComponent } from './containers/main-layout/main-layout.component';
import { MainPageComponent } from './pages/main-page/main-page.component';

const routes: Routes = [
  {
    path: '',
    // This layout component will render in app's router-outlet
    component: MainLayoutComponent,
    children: [
      {
        path: '',
        // This page component will render in mains router-outlet
        component: MainPageComponent,
      },
    ],
  },
];

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

main-layout.component.html

<h1>Main Layout</h1>
<router-outlet></router-outlet>

user-routing.module.ts

const routes: Routes = [
  {
    path: '',
    // This layout component will render in apps router-outlet
    component: UserLayoutComponent,
    children: [
      {
        path: '',
        // This child component will render in users router-outlet
        component: UserPageComponent,
      },
    ],
  },
];

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

user-layout.component.html

<h1>User Layout</h1>
<router-outlet></router-outlet>

I mocked up a stackblitz that demonstrates the solution.

https://stackblitz.com/edit/angular-ivy-oy44ja

Jason White
  • 5,495
  • 1
  • 21
  • 30