angular - 角阵列变化检测
问题描述
我是 Angular 的初学者,我找不到适合我的问题的解决方案。
我有一个包含表的组件,其中填充了项目列表(列表中的每个项目都在另一个组件中),并且第三个组件包含过滤器。过滤器包含多个复选框和一个过滤器按钮。
我将复选框状态的布尔数组从 filterComponent 通过 itemsListComponent 发送到 singleItemComponent 并且它工作正常。我的问题是更改检测。当我使用不同的 NgDoCheck 时,它总是在我单击复选框和过滤器按钮而不是仅过滤器按钮时起作用。
我尝试了 NgOnChanges 但它只工作了一次,然后它没有看到数组中的值有任何变化。
这是我的 SingleItemsComponent(我认为您不需要其他人来帮助我解决这个问题)。看看这个,请给我看任何解决这个问题的例子。
import { Component, OnInit, OnChanges,ViewChild, AfterViewInit, Inject, Input, DoCheck, KeyValueDiffer, KeyValueDiffers, SimpleChanges, SimpleChange, ChangeDetectionStrategy, ChangeDetectorRef, IterableDiffers } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { MatTableDataSource, MatPaginator, MatSort, throwToolbarMixedModesError } from '@angular/material';
import { IPOLine } from 'src/app/models/po-line';
import { POLineService } from 'src/app/services/po-line.service';
@Component({
selector: 'app-po-lines-list',
templateUrl: './po-lines-list.component.html',
styleUrls: ['./po-lines-list.component.css'],
animations: [
trigger('detailExpand', [
state('collapsed', style({ height: '0px', minHeight: '0', display: 'none' })),
state('expanded', style({ height: '*' })),
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
]),
],
})
export class POLinesListComponent implements OnInit, DoCheck{
isLogged = false;
login: string;
dataSource = new MatTableDataSource<IPOLine>();
expandedElement: IPOLine;
errorMessage: string;
response: any;
today = new Date(); // (1990, 0, 1);
isLoadingList = true;
differ: any;
@Input() sentData: boolean[];
_sentData = this.sentData;
ngDoCheck(){
var changes = this.differ.diff(this._sentData);
if (changes){
console.log('changes detected changes detected changes detected changes detected changes detected ');
}
else
console.log('changes not detected changes not detected changes not detected changes not detected ');
}
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
constructor(
//private cd: ChangeDetectorRef,
private differs: KeyValueDiffers,
private _POLineService: POLineService,
private activatedRoute: ActivatedRoute) {
this.differ = differs.find({}).create();
}
ngOnInit() {
// Assign the data to the data source for the table to render
this.login = this.activatedRoute.snapshot.paramMap.get('login');
this._POLineService.getUserPOLines(this.login)
.subscribe(data => {
this.dataSource.data = data;
},
error => {
this.errorMessage = <any>error;
this.isLoadingList = false;
}
,
() => {
// console.log('eee' + this.dataSource.data);
this.isLoadingList = false;
this.dataSource.data.forEach(x => x.isExpired = new Date(x.PromisedDate) < new Date() ? true : false);
}
);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
}
我为代码中的混乱感到抱歉,但我尝试了很多东西,我什至不记得是什么。谢谢你的帮助。
过滤器组件.ts:
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
@Component({
selector: 'app-filters',
templateUrl: './filters.component.html',
styleUrls: ['./filters.component.css']
})
export class FiltersComponent implements OnInit {
@Output() filterByClass = new EventEmitter();
filterByTTR = false;
filterByTBR = false;
filters:boolean[] = [];
constructor() { }
ngOnInit() {
}
log() {
if(!this.filterByTTR)
console.log('TTR not checked');
else
console.log('TTR checked');
if (!this.filterByTBR)
console.log('TBR not checked');
else
console.log('TBR checked');
this.filters[0] = this.filterByTTR;
this.filters[1] = this.filterByTBR;
this.filterByClass.emit(this.filters);
}
FilterComponent.html 的一部分:
<mat-card-content class="col">
<mat-checkbox [checked]="filterByTTR" (change)="filterByTTR = !filterByTTR">TTR</mat-checkbox>
<mat-checkbox [checked]="filterByTBR" (change)="filterByTBR = !filterByTBR">TBR</mat-checkbox>
<!-- <mat-checkbox [(ngModel)]="filterByTBR"ref-TBR>TBR</mat-checkbox> -->
<div class="d-flex justify-content-between">
<button mat-raised-button color="primary">Clear</button>
<button mat-raised-button (click)="log()" color="primary">Apply</button>
</div>
PoLinesCompoenent.ts:
import { Component, OnInit, NgModule, ViewChild, Input } from
'@angular/core';
@Component({
selector: 'app-po-lines',
templateUrl: './po-lines.component.html',
styleUrls: ['./po-lines.component.css']
})
export class POLinesComponent implements OnInit {
count: boolean[];
constructor() { }
ngOnInit(){}
displayCounter(count) {
console.log('first value is: ' + count[0] + ' second value is: ' + count[1]);
this.count = count;
}
PoLinesComponent.html:
<div class="container">
<div class="row">
<div class="side-bar col">
<app-filters (data)='displayCounter($event)'></app-filters>
</div>
<div class="content col">
<app-po-lines-list [sentData]="count"></app-po-lines-list>
</div>
</div>
</div>
解决方案
角度更改检测仅检查是否通过引用更改了某些内容。在您的父组件中,您必须创建一个新数组并将其分配给变量,每当您的数组中的条目发生更改时。只需将数组视为不可变对象。
推荐阅读
- node.js - 使用jade中的参数从一个页面路由到另一个页面
- hyperledger-fabric - Hyperledger Fabric 中的动态通道工件(channel.tx)
- windows - 最新更新后在 Windows 上使用 Docker 后无法恢复使用 Virtual Box
- python - PysimpleGui - 国际象棋示例中关于 size=(1, 1) 和图像着色的混淆
- ionic-framework - 在 Ionic 4 中离开页面时如何停止功能
- java - 如何在 Android 中将字符串解析为日期?
- git - 如何取消对 bitbucket 的推送提交
- ruby-on-rails - Rails - 如何刷新缓存部分中的项目?
- jquery - 从代码“JSON 输入意外结束”中获取以下错误消息
- javascript - 应用验证并在本机反应中设置密码并确认密码相同