如何在角度中检测复杂物体的变化?



我正在做一个有角度的项目。所以我有一个复杂的样式对象,我把它绑定到我的角度组件。

app.component.ts

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
style:any;
ngOnInit() {
this.style = { 
radius:15, 
fill: { 
color: "red" 
}, 
stroke: { 
color: "blue", 
width: 3 
} 
}
}
}

app.component.html

my-component 获取对象并将其与第三方对象一起使用。

my.component.ts

@Component({
selector: 'my-component',
template: `<ng-content></ng-content>`,
})
export class MyComponent implements AfterContentInit {
style: any;
thirdPartyObject: Style;
ngOnInit(): void {
this.style = new Style({
radius: style.radius,
fill: new Fill({ color: style.fill.color }),
stroke: new Stroke({ color: style.stroke.color, width: style.stroke.width })
});
}
ngAfterContentInit(): void {
thirdPartyObject.setStyle(function(){
return this style;          
})
}
}

我正在使用来自 app.component 的样式对象创建第三方样式对象。thirdPartyObject有一个名为setStyle()的函数来获取样式对象。

那么当我在 app.component 中更改样式的属性时,如何更新 my-component?此绑定是不同的。

您可以使用 Angular 的ChangeDetectorRef手动检测更改并切换渲染

@Component({
selector: 'my-component',
template: `<ng-content></ng-content>`,
})
export class MyComponent implements AfterContentInit {
style: any;
thirdPartyObject: Style;
constructor(private ref: ChangeDetectorRef) { }
ngOnInit(): void {
this.style = new Style({
radius: style.radius,
fill: new Fill({ color: style.fill.color }),
stroke: new Stroke({ color: style.stroke.color, width: style.stroke.width })
});
}
ngAfterContentInit(): void {
this.setStylesToThirdPartyObject();
}
setStylesToThirdPartyObject(): void {
thirdPartyObject.setStyle(function(){
return this style;          
});
this.ref.detectChanges();
}
}

在 https://angular.io/api/core/ChangeDetectorRef 上阅读有关CDR的更多信息

下面是一个完整的 Angular 变化检测示例:

import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { CalcComponent } from '../calc-component';
@Component({
selector: 'app-circular-area',
templateUrl: './circular-area.component.html',
styleUrls: ['./circular-area.component.scss']
})
export class CircularAreaComponent implements OnInit {
public render: Boolean;
public radius: number;
public r: number;
constructor(private cdRef: ChangeDetectorRef) { }
**onChange**(event: any, r: number) {
console.log(r);
this.r = Number(r);
this.render = true;
this.cdRef.detectChanges();
this.render = false;
}
ngOnInit() {
this.render = false;
}
}

<div class="mat-elevation-z8">
<form  **(change)="onChange($event,r.value)**">  
<fieldset class="material">
<label>Radius</label>
<hr>
<input #r type="number" placeholder={{radius}} autocomplete="on" value = 5 required> 
</fieldset>
<ng-container *ngIf="!render">
<app-calc-component value={{r.value}} selCalc='circulararea'></app-calc-component>
</ng-container>
</form>
</div>

onChange-方法触发更改检测。另请参阅我的 git 在计算组件中

我建议使用类装饰器将样式传递给@Input子组件,因此 angular 可以跟踪对象style并在检测到更改时重新渲染子组件。

在你的app.component.html:

<your-component [style]="style"></your-component>

在子组件 ts 文件中,应用setStylengOnInitngOnChanges

@Input() style: any;
ngOnInit() {
thirdPartyObject.setStyle(function() { return this.style });
}
ngOnChanges() {
thirdPartyObject.setStyle(function() { return this.style });   
} 

由于style是一个对象,角度跟踪它是参考,而不是属性,所以你必须通过创建新对象来更改style(类似于改变 react 的状态(:

在应用组件 ts 文件中:

changeStyleStroke(){
let newStroke = {
stroke: { 
color: "red", 
width: 3 
} 
};
//Update style this way will trigger change detection that detect changes and re-render your component
this.style = {...this.style, ...stroke};
}

最新更新