具有可观察到的重新渲染问题的 Angular 组件

时间:2021-05-29 10:03:14

标签: angular service responsive-design observable state

我为自己编写了一个服务,它提供了一个可观察对象,观察媒体断点并根据断点返回一个值。在我的角度组件中,我正在调用一个带参数的方法,以便根据屏幕断点更改列的跨度。订阅功能仅在断点按预期更改时触发,但是每当我调整浏览器窗口的大小时,角度组件都会重新渲染并调用我放置该方法的每个 dom 元素,该方法虽然状态没有改变,但会导致性能问题。

服务:

   import { Inject, Injectable } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { map, shareReplay } from 'rxjs/operators';
import { Observable, Subject, Subscription } from 'rxjs';

@Injectable()
export class MatGridResponsivenessService {

  private cols$: Observable<number>;

  constructor(private breakpointObserver: BreakpointObserver, 
             @Inject('maxGridSize') private maxGridSize:number = 14)
            {
            }

  breakpointObservableStart():Observable<number> {
    this.cols$ = this.breakpointObserver
                       .observe([Breakpoints.XLarge, Breakpoints.Large, Breakpoints.Medium, Breakpoints.Small, Breakpoints.XSmall])
                              .pipe(
                                  map((result) => {
                                    console.log(result);
                                    if(result.breakpoints[Breakpoints.XSmall]) {
                                      return 1;
                                    } else if(result.breakpoints[Breakpoints.Small]) {
                                      return 2;
                                    } else if(result.breakpoints[Breakpoints.Medium]) {
                                      return 3;
                                    } else
                                      return 4;
                                    }),
                                   shareReplay()
                              );
    return this.cols$;
  }      


  colspan(cols:number, large:number, medium:number = this.maxGridSize, small:number = this.maxGridSize, xsmall:number = this.maxGridSize):number {
    console.log(cols);
      if(cols === 1) {
        return xsmall;
      } else if(cols === 2) {
        return small;
      } else if(cols === 3) {
        return medium;
      }
      else return large;
  }

    
}

组件:

import { AfterContentInit, Component, OnInit} from '@angular/core';
import {MatGridListModule} from '@angular/material/grid-list';
import { MatGridResponsivenessService } from 'src/app/services/mat-grid-responsiveness.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-component',
  templateUrl: './component.component.html',
  styleUrls: ['./component.component.css', '/src/css/scrollBar.css'],
  providers: [MatGridResponsivenessService, {provide: 'maxGridSize', useValue: 14}]
})
export class PersonbearbeitenTelefonComponent implements OnInit, AfterContentInit {

  cols:any;
  private colsSubscription: Subscription;
  cl;

  constructor(public responsiveCols: MatGridResponsivenessService)
  {
  }

  ngOnInit() 
  {
    this.cl = this.responsiveCols;
  }

  ngAfterContentInit() {
      this.colsSubscription = this.responsiveCols.breakpointObservableStart().subscribe(res => {
        console.log("should rerender")
        this.cols = res;
    })
  }

  ngAfterViewInit()
  {
    this.rows.changes.pipe(takeWhile(()=>this.alive)).subscribe(() => {
      if (this.rows.length)  
      {
          this.rows.last.nativeElement.focus();
      }
    }); 
  }


  ngOnDestroy()
  {
    this.colsSubscription.unsubscribe();
  }

模板:

<mat-grid-list cols="14" rowHeight="55px" class="leftaligned scrollbarHiddenX scrollbarHiddenY" [gutterSize]="'10px'"> 
  <mat-grid-tile [colspan]="responsiveCols.colspan(cols, 2, 2, 3, 5)">
    <strong>Field1</strong>
  </mat-grid-tile>

  <mat-grid-tile [colspan]="responsiveCols.colspan(cols, 1, 12, 11, 9)" style="justify-content: start;">
    <button mat-button><jxicon icon="addAlt" [medium]="true"></jxicon></button>
  </mat-grid-tile>
   <mat-grid-tile [colspan]="responsiveCols.colspan(cols, 2, 2, 3, 5)">
    <strong>Field2</strong>
  </mat-grid-tile>
</mat-grid-list>

0 个答案:

没有答案
相关问题