Как бы я переключил свою боковую панель в другой компонент? - PullRequest
2 голосов
/ 12 марта 2019

У меня есть компонент заголовка с мат-панелью инструментов, и у меня есть кнопка, которую я хочу использовать для переключения панели sidenav, которая находится в другом компоненте. Как бы я переключил свою боковую панель в другой компонент?

Я хочу переключить его под компонент заголовка.

https://stackblitz.com/edit/angular-adkpkv

Я скопировал весь свой проект здесь, но я не могу заставить его работать в stackbitz. Хотя он работает локально.

Ответы [ 3 ]

2 голосов
/ 12 марта 2019

Я предлагаю вам воспользоваться услугами . Преимущества состоят в том, что с ними очень легко начать и легко использовать. Кроме того, сервис доступен для каждого компонента или даже для других сервисов, вы можете переключать боковую панель с любого количества различных компонентов. Если вы знакомы, например, с C #, служба ведет себя подобно одиночному в C #.

Таким образом, вы должны создать новый сервис, набрав ng g s toggle в Angular CLI.

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

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

    constructor() { }
}

Решение 1:

Это более простой способ без приятной анимации. Самый простой способ переключить компонент боковой панели, поместив его уже в правильное положение, но установив display: none. Затем вы используете ngClass, чтобы установить класс css для компонента боковой панели, в зависимости от свойства. Примените этот код к тегу самого верхнего компонента боковой панели.

[ngClass]="{'show-sidebar': toggleService.showSidebar}"

Чтобы это работало, вы должны создать новый класс CSS в боковой панели CSS. Добавить:

.show-sidebar { 
    display: block;
}

После этого вы добавляете свойство в сервис.

private _showSidebar = false;
public get showSidebar(): boolean{
    return this._showSidebar;
}
public set showSidebar(v : boolean) {
    this._showSidebar = v;
}

Теперь вы внедряете сервис в компонент боковой панели и назначаете его свойству, чтобы иметь возможность ссылаться на сервис в вашем html-файле. Таким образом, вы можете использовать значение bool showSidebar для переключения класса show-sidebar css.

Следующим шагом будет внедрение службы в компонент, где находится кнопка, который вы используете для переключения боковой панели. После этого вы добавляете событие нажатия на кнопку, где вы изменяете значение toggleService.showSidebar на true.


Решение 2:

Теперь, если вы хотите использовать, например, Angular Animations вы можете добавить свойство к сервису, которое вы можете изменить из одного компонента, и это изменение переключит состояние анимации, чтобы оживить боковую панель для перемещения на экран.

private _sideBarState = 'inactive';
public get sideBarState(): string {
    return this._sideBarState;
}
public set sideBarState(v : string) {
    this._sideBarState = v;
}

Затем вы привязываете sliderState к вашему компоненту в формате html, то есть в html компонента боковой панели. Просто добавьте это в тег самого верхнего на боковой панели.

[@sliderState]="toggleService.sideBarState"

Чтобы сделать это, вы должны вставить toggleService в компонент боковой панели. Если у вас есть вопросы по этому поводу, просто спросите меня.

После этого вам нужно добавить различные анимации в декоратор компонента, который вы хотите анимировать, компонент боковой панели.

@Component({
selector: 'core-detail-page',
templateUrl: './detail-page.component.html',
styleUrls: ['./detail-page.component.scss'],
animations: [
    trigger('sliderState', [
        state('active', style({
            left: '0',
            display: 'block'
        })),
        state('inactive', style({
            left: '-300px',
            display: 'none'
        })),
        transition('inactive => active', animate('300ms ease-out')),
        transition('active => inactive', animate('300ms ease-out'))
    ])
]

}) * 1 054 *

Это всего лишь некоторые фиктивные значения, в которых я притворяюсь, что ваш компонент боковой панели установлен на position: absoulte и расположен прямо рядом с вашим экраном, эти -300px. И как только вы измените значение sidebarState в toggleService на active, свойства left и display будут анимированы в соответствии с вашими определениями анимации. Вы можете анимировать любую недвижимость, какую захотите.

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

toggleSidebar() {
    this.toggleService.sideBarState = 'active';
}
0 голосов
/ 12 марта 2019

У меня была такая же проблема несколько недель назад, и я наткнулся на эту статью, которая мне очень помогла. Это объясняет, как компоненты взаимодействуют, переключая боковую панель:)

https://medium.com/@mirokoczka/3-ways-to-communicate-between-angular-components-a1e3f3304ecb

ура!

0 голосов
/ 12 марта 2019

Вы должны внести несколько изменений (ниже) в ваш существующий stackblitz , который

  • убрать каждый клик (меню бургера) из header.component
  • получить это значение внутри app.component (родительский) и передать дочернему
  • обработать этот клик в side-nav.component (дочерний элемент)

Внесите эти изменения и посмотрите, как переключается переход от одного компонента к другому ... Я добавил в дочерний тег <mark>, чтобы проверить, действительно ли получено значение.

измените свой header.component.ts на:

import { Component, OnInit, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
  @Output() menuState = new EventEmitter();

  constructor() { }
  opened: boolean;
  showMenu = false; /* false by default, since hidden */
  toggleMenu() {
      console.log("inside toggleMenu");
      this.showMenu = !this.showMenu;
      this.menuState.emit(this.showMenu);
   }
  ngOnInit() {
  }

}

ваш header.component.html будет:

<mat-toolbar>
    <mat-toolbar-row>
        <a href="" class="site-logo">
            <h2>TEST APP</h2>
        </a>
        <button mat-icon-button (click)="toggleMenu()"> 
              <mat-icon>menu </mat-icon>
          </button>
      <span class="example-spacer"></span>
      <mat-icon class="example-icon"  matBadge="15" matTooltip="Recent changes">notifications</mat-icon>
      <mat-icon class="example-icon"  matTooltip="Info or how to contact us">help</mat-icon>
      <mat-icon class="example-icon"  matTooltip="Your account information"> account_circle</mat-icon>
    </mat-toolbar-row>

</mat-toolbar>

ваш app.component.ts будет:

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'This is the copy of the Expense App';
  subMenuState:boolean = false;
  burgerClicked(evnt){
    this.subMenuState = evnt;
    console.log("inside burgerClicked: pls. change showMenu to be:",this.subMenuState);
  }

}

ваш app.component.html будет:

<h1>{{title}}</h1>
<app-header (menuState)='burgerClicked($event)'></app-header>
<app-side-nav [subMenuState]="subMenuState"></app-side-nav>
<router-outlet></router-outlet>
<app-footer></app-footer>

ваш side-nav.component.ts будет

import { Component, OnInit, Input, OnChanges } from '@angular/core';

@Component({
  selector: 'app-side-nav',
  templateUrl: './side-nav.component.html',
  styleUrls: ['./side-nav.component.css']
})
export class SideNavComponent implements OnInit, OnChanges {
  @Input() subMenuState;
  constructor() { }
  opened: boolean;
  showMenu = true;
  toggleMenu() {
      this.showMenu = !this.showMenu;
   }
  ngOnInit() {
  }

  ngOnChanges(){
    console.log("inside ngOnChanges with subMenuState: ",this.subMenuState );
    this.showMenu = this.subMenuState;
  }

}

в вашем side-nav.component.html я добавил строку вверху, чтобы убедиться, что значение переключается правильно

<mark> Show menu (inside side-nav.component) ? {{showMenu}} </mark>
<mat-sidenav-container >
  <mat-sidenav #sidenav mode="side"  mat-disable-backdrop #start >
      <mat-nav-list>
          <a mat-list-item routerLink="/">  
              <mat-icon> home</mat-icon>
              <span> All Reports </span>
          </a>
          <a mat-list-item routerLink="/entries">  
              <mat-icon>  assignment </mat-icon>
              <span> Reports Per Business </span>
          </a>
          <a mat-list-item (click)="toggleMenu()">
                  <mat-icon mat-list-icon>business</mat-icon>Maintenance
                  <mat-icon *ngIf="!showMenu">chevron_right</mat-icon>
                  <mat-icon *ngIf="showMenu">expand_more</mat-icon>
                </a>
                <mat-nav-list class="sidenav-submenu" *ngIf="showMenu">
                  <a mat-list-item  routerLink="/new-entry"> New Report</a>
                  <a mat-list-item > New User</a>
                  <a mat-list-item > New Business</a>
                </mat-nav-list>
                <a mat-list-item >  
                      <mat-icon> account_circle</mat-icon>
                      <span> Login </span>
                  </a>
      </mat-nav-list>

  </mat-sidenav>

</mat-sidenav-container>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...