从 angular 中的另一个组件切换 sidenav

toggle sidenav from another component in angular

我想从 Angular 中的另一个组件切换 sidenav。我有 3 个 child 组件:menu、content、header。按钮打开 header component.I 想要点击按钮然后菜单应该切换。

header.ts

export class HeaderComponent implements OnInit {
  constructor(public service: SharedService) {}

  ngOnInit() {}

  toggleMenu() {
    this.service.flag = !this.service.flag;
    this.service.flagChange.emit(this.service.flag);
  }
}

header.html

<div>
  <a href="">
    <i class="fas fa-bars text-white barsIcon" ` (click)="toggleMenu()"></i>
  </a>
</div>

menu.ts

export class MenuComponent implements OnInit {
  constructor(public service: SharedService) {
    this.service.flagChange.subscribe((res) => this.service.flag);
  }

  ngOnInit() {}
}

menu.html

<div>
  <ul>
    <li>
      <a routerLink="/dashboard">Dashboard</a>
    </li>
    <li>
      <a routerLink="/user">User</a>
    </li>

    <li>
      <a routerLink="">Currency</a>
    </li>
    <li>
      <a routerLink="/report">Report</a>
      <ul>
        <li>
          <a routerLink="">Report1</a>
        </li>
        <li>
          <a routerLink="">Report2</a>
        </li>
        <li>
          <a routerLink="">Report3</a>
        </li>
      </ul>
    </li>
  </ul>
</div>

service.ts

@Injectable({
  providedIn: "root",
})
export class SharedService {
  public flag: boolean = false;
  public flagChange = new EventEmitter<boolean>();

  constructor() {}
}

你不是那个票价,但你应该使用 BehaviorSubject 而不是 EventEmitter
发射器 a 用于@Output()

这里有一些小改动。
我也重构了一点你的代码;)

header.ts

export class HeaderComponent {
  constructor(public sharedService: SharedService) {}
}

header.html

<div>
  <a href="">
    <i class="fas fa-bars text-white barsIcon" (click)="sharedService.toggleMenu()"></i>
  </a>
</div>

menu.ts

export class MenuComponent implements OnInit, OnDestroy {
  protected _unsubscribe$: Subject<void> = new Subject();

  flag?: boolean

  constructor(private _sharedService: SharedService) {}

  ngOnInit() {
    this._sharedService.onFlagChange$
      .pipe(takeUntil(this._unsubscribe$))
      .subscribe((value) => {
        this.flag = value
      })
  }

  ngOnDestroy(): void {
    this._unsubscribe$.next();
    this._unsubscribe$.complete();
  }
}

menu.html

<div [class.hidden]="!flag"> <!-- or *ngIf, as you wish ;) -->
  <ul>
    <li>
      <a routerLink="/dashboard">Dashboard</a>
    </li>
    <li>
      <a routerLink="/user">User</a>
    </li>

    <li>
      <a routerLink="">Currency</a>
    </li>
    <li>
      <a routerLink="/report">Report</a>
      <ul>
        <li>
          <a routerLink="">Report1</a>
        </li>
        <li>
          <a routerLink="">Report2</a>
        </li>
        <li>
          <a routerLink="">Report3</a>
        </li>
      </ul>
    </li>
  </ul>
</div>

service.ts

@Injectable({
  providedIn: "root",
})
export class SharedService {
  flag = false;
  onFlagChange$: BehaviorSubject<boolean> = new BehaviorSubject(this.flag);

  constructor() {}

  toggleMenu() {
    this.flag = !this.flag;
    this.onFlagChange$.next(this.flag); // Here, .next instead of .emit
  }
}

错误

  1. 使用 BehaviorSubject 代替 EventEmitter

优化

  1. 始终取消订阅 observable!

重构

  1. 如果您已经为其添加了值,请不要声明 :boolean,这是隐含的。
  2. service
  3. 中移动切换逻辑
  4. 如果不用就不要声明ngOnInit
  5. 如果 html 文件中没有使用,则创建服务 private