簡體   English   中英

angular 2 - 如何在某些組件中隱藏導航欄

[英]angular 2 - how to hide nav bar in some components

我在 nav.component.html 中單獨創建了導航欄,如何在一些組件(如 login.component)中隱藏導航欄。

導航組件.html

<nav class="navbar navbar-default navbar-fixed-top navClass">
    <div class="container-fluid">
        <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed"
                        (click)="toggleState()">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>

        </div>
         <div class="collapse navbar-collapse"
              [ngClass]="{ 'in': isIn }">
          enter code here   <ul class="nav navbar-nav">
               <li class="active"><a href="#">Home</a></li>
               <li><a href="#">about</a></li>

            </ul>

        </div>
    </div>
</nav>

整個應用程序中經常需要導航欄控件和格式設置,因此 NavbarService 很有用。 在您需要的地方注入那些組件。

導航欄.service.ts:

import { Injectable } from '@angular/core';

@Injectable()
export class NavbarService {
  visible: boolean;

  constructor() { this.visible = false; }

  hide() { this.visible = false; }

  show() { this.visible = true; }

  toggle() { this.visible = !this.visible; }

  doSomethingElseUseful() { }

  ...
}

導航欄.component.ts:

import { Component } from '@angular/core';
import { NavbarService } from './navbar.service';

@Component({
  moduleId: module.id,
  selector: 'sd-navbar',
  templateUrl: 'navbar.component.html'
})

export class NavbarComponent {

  constructor( public nav: NavbarService ) {}
}

導航欄.component.html:

<nav *ngIf="nav.visible">
 ...
</nav>

示例.component.ts:

import { Component, OnInit } from '@angular/core';
import { NavbarService } from './navbar.service';

@Component({
})
export class ExampleComponent implements OnInit {

  constructor( public nav: NavbarService ) {}
}
ngOnInit() {
  this.nav.show();
  this.nav.doSomethingElseUseful();
}

通過向 route.module 中的路由添加數據對象,我能夠在不使用導航/工具欄服務的情況下解決此問題。 我擴展了Todd Motto 向頁面添加動態標題的示例,並為路徑中的數據對象添加了toolbar: false/true 然后我在我的 toolbar.component 中訂閱了路由器事件。 使用 Todd 的事件偵聽器 func,我讀取路徑對象並使用布爾值來設置工具欄可見或不可見。

無需服務,可在 pagerefresh 上工作。

路由模塊

...
const routes: Routes = [
{ path: 'welcome', component: WelcomeComponent, data: { title: 'welcome', toolbar: false} }, ...];

工具欄組件

constructor(private router: Router, private activatedRoute: ActivatedRoute, public incallSvc: IncallService) {
    this.visible = false; // set toolbar visible to false
  }

  ngOnInit() {
    this.router.events
      .pipe(
        filter(event => event instanceof NavigationEnd),
        map(() => this.activatedRoute),
        map(route => {
          while (route.firstChild) {
            route = route.firstChild;
          }
          return route;
        }),
      )
      .pipe(
        filter(route => route.outlet === 'primary'),
        mergeMap(route => route.data),
      )
      .subscribe(event => {
        this.viewedPage = event.title; // title of page
        this.showToolbar(event.toolbar); // show the toolbar?
      });
  }

  showToolbar(event) {
    if (event === false) {
      this.visible = false;
    } else if (event === true) {
      this.visible = true;
    } else {
      this.visible = this.visible;
    }
  }

工具欄.html

<mat-toolbar color="primary" *ngIf="visible">
  <mat-toolbar-row>
    <span>{{viewedPage | titlecase}}</span>
  </mat-toolbar-row>
</mat-toolbar>

添加到Dan的答案。

完整答案還需要一個細節。 這也是注冊NavbarService作為從整個應用程序提供商app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { SharedModule } from './shared/shared.module';

import { AppComponent } from './app.component';
import { NavbarModule } from './navbar/navbar.module';
import { NavbarService } from './navbar/navbar.service';

import { AppRoutingModule, routedComponents } from './routing.module';

@NgModule({
    imports: [
        BrowserModule, FormsModule, HttpModule,
        NavbarModule,
        SharedModule,
        AppRoutingModule
    ],
    declarations: [
        routedComponents,
    ],
    providers: [
        // Here we register the NavbarService
        NavbarService  
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

我喜歡上面丹的這個答案 但是,它確實會創建一些更新控制台錯誤,這是我不希望在生產應用程序中出現的。 我建議改用這種方法: answer

使用 canDeactivate 來完成實現也可能會有所幫助。 我隱藏導航欄的地方,例如在登錄時,我添加了一個導航“canDeactive”服務:

{ path: 'login', component: LoginComponent, canDeactivate: [NavigateAwayFromLoginDeactivatorService]  },

停用服務如下所示:

import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { LoginComponent } from "app/user/login/login.component";
import { NavbarTopService } from "app/navbar-top/navbar-top.service";

@Injectable()
export class NavigateAwayFromLoginDeactivatorService implements CanDeactivate<LoginComponent> {

  constructor(public nav: NavbarTopService) {  }

  canDeactivate(target: LoginComponent) {
    this.nav.show();
    return true;
  }
}

這樣,我只能在登錄時隱藏,不需要在每個其他組件上調用show()

您可以在導航所在的組件上使用 ngIF 指令

   <nav *ngIf="this.currentRoute!=='login'" navigation>
   </nav>

獲得當前路線后:

  this.router.events.subscribe(event => {
  if (event.constructor.name === "NavigationEnd") {
    this.name = (<any>event).url.split("/").slice(-1)[0];
    this.isLogin = this.currentRoute === 'login';
  }
})

在模板中添加 *ngIf='!showNav'

<nav class="navbar navbar-default navbar-fixed-top navClass" *ngIf='!showNav' >

在 LoginComponent 中

showNav = true;

這將顯示所有頁面的導航其余部分,如果您想隱藏在任何頁面中,只需showNav = true; 在那個組件中。

這個怎么運作 :

首先,它會檢查showNav變量,但它不可用,因此對於我們要顯示菜單的其他頁面,它將返回 false,因此需要在任何其他頁面上聲明該變量。

在登錄頁面中,我們將值設置為 true,因此它將使其為 false 並隱藏導航。

為了使其正常工作,還可以在您導入 NavbarService 的任何地方添加“Providers”

navbar.component.ts 和 example.component.ts

@Component({
  moduleId: module.id,
  selector: 'sd-navbar',
  templateUrl: 'navbar.component.html',
  providers: [NavbarService ]
})

此問題的另一個解決方案,特別是如果您希望從其他控件打開/關閉/切換/側導航欄,則是在服務中保存對側導航欄的引用,如下所述:

https://stackoverflow.com/a/48076331/1013544

這對我來說效果很好,因為我有一個應用程序,其中側導航更像是根元素,而路由器組件是它的內容,因此當側導航菜單打開時,它們將在后台禁用。

如果您要隱藏 mat-sidenav 元素,那么 JaganY上面鏈接答案是最佳答案。 您永遠不應該讓像這樣的簡單代碼需要更改檢測。 以下是其他類型元素的示例:

app.component.html

    <nav #rNav>
      <app-rightnav></app-rightnav>
    </nav>

app.component.ts

  @ViewChild('rNav') rNav!: ElementRef;

  constructor(public nav: NavbarService) { }

  ngAfterViewInit(): void {
    this.nav.setRight(this.rNav);
  }

導航欄.service.ts

import { Injectable, ElementRef } from '@angular/core';

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

  private right!: ElementRef;
  private visible!: boolean;

  hideR() { 
    this.visible = false;
    this.right.nativeElement.style.display = 'none';
  }

  showR() { 
    this.visible = true; 
    this.right.nativeElement.style.display = 'block';
  }

  toggleR() { this.visible ? this.hideR() : this.showR(); }

  setRight(e: ElementRef) {
    this.right = e;
  }
}

子組件.html

constructor() {
  this.nav.hideR(); // or this.nav.showR();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM