Показать / скрыть индикатор выполнения, размещенный в другом компоненте - PullRequest
0 голосов
/ 09 мая 2020

Я ладья от ie до Angular. Я хочу показать / скрыть mat-progress-bar, который находится на ToolbarComponent, от любого другого компонента.

Я уже искал отношения родитель / потомок между компонентами, но здесь это не так (по крайней мере, это то, что Думаю).

Это моя структура проекта:

  • src
    • app
    • components
      • company
        • company.component.ts
    • общий
      • компоненты
        • панель инструментов
          • toolbar.component .ts

Как мне получить доступ к mat-progress-bar на ToolbarComponent из CompanyComponent, например? Или есть лучший способ делать то, что я хочу?

Ответы [ 2 ]

1 голос
/ 09 мая 2020

Если вы хотите скрыть панель инструментов на некоторых экранах, например, на экране входа в систему, лучший способ сделать это с вашей структурой - использовать Observable и подписаться на нее глобально, чтобы изменить что-либо в любом месте ваших компонентов. Для этого определите хранилище следующим образом: -

//Store.js
import {Observable, BehaviorSubject} from 'rxjs';

export class Store<T> {
    state$: Observable<T>;
    private _state$: BehaviorSubject<T>;

    protected constructor (initialState: T) {
        this._state$ = new BehaviorSubject(initialState);
        this.state$ = this._state$.asObservable();
    }

    get state (): T {
        return this._state$.getValue();
    }

    setState (nextState: T): void {
        this._state$.next(nextState);
    }
}

Затем определите файл, скажем,

//ToolbarState.ts
const state = {
  show: false
}
export class ToolbarState {
  state: {show: boolean} = state;
}

Затем файл хранилища для связи с этим состоянием скажем: -

//ToolbarStore.ts
import { Injectable } from '@angular/core';
import { Store } from '../store';
import { ToolbarState } from './ToolbarState';

@Injectable()
export class ToolbarStore extends Store<ToolbarState> {
  constructor () {
    super(new ToolbarState());
  }

  showToolbar (): void {
    this.setState({
      ...this.state,
      state: {...this.state.state, show: true}
    });
  }

  hideToolbar (): void {
    this.setState({
      ...this.state,
      state: {...this.state.state, show: false}
    });
  }
}

поэтому в компоненте вашей компании вы можете сделать что-то вроде ниже: -

import { Component, OnInit } from '@angular/core';
import { ToolbarStore } from '../ToolbarStore';

@Component({
  selector: 'company',
  templateUrl: './company.component.html',
  providers: [ToolbarStore]
})
export class CompanyComponent implements OnInit {

  constructor(public store: ToolbarStore) { }

  ngOnInit() {
    setTimeout(() => {
      this.store.showToolbar(); // store function to show toolbar
    });
  }

  hideToolbar(){
    this.store.hideToolbar(); // store function to hide toolbar
  }
}

затем в Toolbar.component.ts

import { Component, OnInit, OnDestory } from '@angular/core';
import { ToolbarStore } from '../ToolbarStore';
import {Subscription} from 'rxjs';

    @Component({
      selector: 'toolbar',
      templateUrl: './toolbar.component.html',
      providers: [ToolbarStore]
    })
    export class ToolbarComponent implements OnInit, OnDestory {


      Subscription: Subscription = new Subscription();
      show: boolean;
      constructor(public store: ToolbarStore) { }

      ngOnInit() {
        this.Subscription.add(
          this.store.state$.subscribe(data => {
            this.show = data.state.show;
          });
        );
      }

      ngOnDestory(){
        this.Subscription.unsubscribe();
      }

    }

свой app.module. ts должен быть таким: -

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

import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
import { CompanyComponent } from './company.component';
import { ToolbarComponent } from './toolbar.component';
import { ToolbarStore } from './toolbar-store';

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent, CompanyComponent, ToolbarComponent ],
  providers: [ToolbarStore],
  exports: [ToolbarComponent],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

, а затем, наконец, в вашем toolbar.component. html file: -

<mat-progress-bar *ngIf="show"
          class="example-margin"
          [color]="color"
          [mode]="mode"
          [value]="value"
          [bufferValue]="bufferValue">
      </mat-progress-bar>

Вы можете узнать больше о Behavior Subject и Observables по следующим ссылкам: - https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject

Рабочий пример приведенного выше кода в stackblitz по следующей ссылке, здесь вы можете управлять элементами внутри компонента панели инструментов из компонента компании: - https://stackblitz.com/edit/angular-ivy-7cmgvm

0 голосов
/ 14 мая 2020

Вы можете использовать Shared Service для управления «статусом загрузки» (например, ответ Усмана Али Хана), но, следуя передовой практике, он должен быть в SharedModule, чтобы использовать его в любом компоненте.

Если вы думаете использовать его для HTTP-вызовов, вы можете использовать перехватчики.

У меня есть пример использования SharedModule + SharedService + Interceptors в моем репозитории: https://github.com/cmandamiento/angular-architecture-base

...