Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度材质:需要额外的交互才能触发渲染_Angular_Typescript_Angular Material - Fatal编程技术网

Angular 角度材质:需要额外的交互才能触发渲染

Angular 角度材质:需要额外的交互才能触发渲染,angular,typescript,angular-material,Angular,Typescript,Angular Material,我在使用角度材质时遇到了一种奇怪的行为:一些组件需要额外的事件(如在感兴趣的div上单击或鼠标移动)来触发实际渲染。 例如,对于mat表格,当它加载新行时,仍会显示一些空行,只要我向下滚动或单击其中一行,它们就会消失。 另一个例子是对话框:当我在边界外单击时,什么也没有发生,但如果我再次单击或滚动,它就会消失。 这是我的版本。 谢谢 首先,谢谢你的回答。 我注意到所有问题都链接到mat表:导致问题的对话框由表内的按钮触发,如果 我把它移到外面,它工作正常。 该表的组成部分如下所示: expor

我在使用角度材质时遇到了一种奇怪的行为:一些组件需要额外的事件(如在感兴趣的div上单击或鼠标移动)来触发实际渲染。 例如,对于mat表格,当它加载新行时,仍会显示一些空行,只要我向下滚动或单击其中一行,它们就会消失。 另一个例子是对话框:当我在边界外单击时,什么也没有发生,但如果我再次单击或滚动,它就会消失。 这是我的版本。 谢谢

首先,谢谢你的回答。 我注意到所有问题都链接到mat表:导致问题的对话框由表内的按钮触发,如果 我把它移到外面,它工作正常。 该表的组成部分如下所示:


export class MainComponent implements OnInit {
    
    dataSource : MyTableSource;
    @ViewChild(MatTable, {static:true}) table: MatTable<any>;
    dtOptions: any = { 
            displayedColumns : [ 'colA', 'colB', 'colC', 'colD'],
            search : { value : "" } ,
            order : { name : 'values' , asc : true },
            subset : [] , 
            pageSize : 10,
            pageIndex : 0,
            draw : 0 , 
            recordsTotal : 0, 
            recordsFiltered : 0};

    constructor(public dialog: MatDialog,
            private _snackBar: MatSnackBar,private trackService: TracksService) {
    };
   ngOnInit() {
        this.dataSource = new KmerTableSource(this.trackService);
   }
   refreshTable(event?:any){
        if ( event){
            if ( event.pageSize){
                this.dtOptions.pageSize=event.pageSize;
                this.dtOptions.pageIndex=event.pageIndex;
            }
            if (event.active){
                this.dtOptions.order.name = event.active;
                this.dtOptions.order.asc = event.direction == "asc";
            }
        }
        
        this.dataSource.loadData(this.dtOptions);
    }
    
}
   

导出类MainComponent实现OnInit{
数据源:MyTableSource;
@ViewChild(MatTable,{static:true})table:MatTable;
dtOptions:any={
显示列:['colA'、'colB'、'colC'、'colD'],
搜索:{值:},
顺序:{name:'values',asc:true},
子集:[],
页面大小:10,
页面索引:0,
抽签:0,
记录总数:0,
已筛选的记录:0};
构造函数(公共对话框:MatDialog,
私人(snackBar:matsnakbar,私人轨道服务:tracks服务){
};
恩戈尼尼特(){
this.dataSource=新的KmerTableSource(this.trackService);
}
刷新表(事件?:任何){
如果(事件){
if(event.pageSize){
this.dtOptions.pageSize=event.pageSize;
this.dtOptions.pageIndex=event.pageIndex;
}
如果(事件激活){
this.dtOptions.order.name=event.active;
this.dtOptions.order.asc=event.direction==“asc”;
}
}
this.dataSource.loadData(this.dtOptions);
}
}
html

<table mat-table matSort (matSortChange)="refreshTable($event)" [dataSource]="dataSource" >
                        <ng-container matColumnDef="importance">
                            <th mat-header-cell *matHeaderCellDef  mat-sort-header>Col A</th>
                            <td mat-cell *matCellDef="let row">{{row.A}}</td>
                        </ng-container>
                        <ng-container matColumnDef="kmer">
                            <th mat-header-cell *matHeaderCellDef  mat-sort-header>Col B</th>
                            <td mat-cell *matCellDef="let row">{{row.B}}</td>
                        </ng-container>
                        <ng-container matColumnDef="position">
                            <th mat-header-cell *matHeaderCellDef  mat-sort-header>Col C</th>
                            <td mat-cell *matCellDef="let row">{{row.C}}</td>
                        </ng-container>
                        
                        <tr mat-header-row *matHeaderRowDef="dtOptions.displayedColumns;sticky : true;"></tr>
                        <tr mat-row cdk-row *matRowDef="let row; columns: dtOptions.displayedColumns"></tr>
                    </table>



科拉
{{row.A}}
B列
{{row.B}}
C柱
{{row.C}}
数据源


@Injectable({
  providedIn: 'root'
})


export class MyTableSource implements DataSource<DataPoint> {
  private dataSubject = new BehaviorSubject<DataPoint[]>([]);
    
  constructor(private trackService :TracksService ) { }

  connect(collectionViewer: CollectionViewer): Observable<DataPoint[]> {
      return this.dataSubject.asObservable();
  }

  disconnect(collectionViewer: CollectionViewer): void {
      this.dataSubject.complete();
  }
  
  loadData(request : any) {
      this.trackService.getDataTable(request).pipe(
              catchError(()=>of([])),
      ).subscribe(response => {
          this.dataSubject.next(response);
       });
  }
  
}

  

@注射的({
providedIn:'根'
})
导出类MyTableSource实现数据源{
私有数据主体=新行为主体([]);
构造函数(专用跟踪服务:跟踪服务){}
连接(collectionViewer:collectionViewer):可观察{
返回此.dataSubject.asObservable();
}
断开连接(collectionViewer:collectionViewer):无效{
this.dataSubject.complete();
}
loadData(请求:任何){
这个.trackService.getDataTable(请求).pipe(
catchError(()=>of([]),的,
).订阅(响应=>{
this.dataSubject.next(响应);
});
}
}
轨道服务(我使用的是electron)


@可注射({
providedIn:'根'
} )
导出类TracksService{
受保护请求:编号=0;
受保护的ipc:ipc;
构造函数(受保护的http:HttpClient){
如果((窗口).require){
试一试{
this.ipc=(window).require(“electron”).ipc渲染器;
}捕获(错误){
投掷误差;
}
}否则{
控制台。警告(“无法加载电子ipc”);
}
}
getDataTable(dataTablesParameters:any):可观察{
var id=this.request;
该请求+=1;
this.ipc.send(“getData”、id、dataTablesParameters);
返回新的可观察对象(观察者=>{
此.ipc.once(“getData-”+id,(事件,参数)=>{
dataTablesParameters.recordsTotal=arg.recordsTotal;
dataTablesParameters.recordsFiltered=arg.recordsFiltered;
下一步(参数数据);
});
});
}
}

我也遇到了类似的情况,因为我使用了从Input()值获取其值的材质组件。需要在ngOnChanges或NgoAfterContentInit上使用ChangeDetectorRef

export class MyComponent {
  @Input() data: string[];

  constructor(private cd: ChangeDetectorRef) { }

  ngAfterContentInit() {
    this.cd.detectChanges();
  }
}
您可能需要更改策略以推动:

@Component({
...
changeDetection: ChangeDetectionStrategy.OnPush
...
})


使用NgZone和ChangeDetectorRef解决:可能调用是在MatTable组件内部进行的,订阅中的更改没有在主组件中呈现

在主要组成部分:

refreshTable(event?:any){
        ...
        this.dataSource.loadData(this.dtOptions).then(()=>this.cd.markForCheck());
    }

数据源的loadData现在必须返回一个承诺,以便在加载后触发markForCheck

loadData(request : any) : Promise<void> {
return new Promise(resolve, reject )=>{...})
}

感谢@gsa.interactive提供的ChangeDetectorRef提示

,您能否添加一个发生这种行为的简单示例?我强烈怀疑没有触发ChangeDetection。在
ngOnChanges
中使用
detectChanges
是您绝对不想做的事情。使用限制性更强的
ChangeDetectionStrategy
例如
onPush
确实是可取的(从性能上看),但无助于解决这个问题。感谢您的提示,但我认为问题来自数据表,而不是对话框本身
refreshTable(event?:any){
        ...
        this.dataSource.loadData(this.dtOptions).then(()=>this.cd.markForCheck());
    }

loadData(request : any) : Promise<void> {
return new Promise(resolve, reject )=>{...})
}
this.zone.run(()=>{this.dialog.open(...)}));