Reactive@Input未正确获取角度数据



我有一个父组件(container.component(和一个子组件(plotting.component(。

用户可以从容器上传文件。一个提交按钮将把这些数据发送到绘图组件中。不幸的是,我只能将数据从容器发送到绘图中一次。如果我试图来回上传多个数据,那就不起作用了。打印组件未使用正确的数据进行更新。

这是我的container.component.html:

<div class="input-group">
<div class="custom-file">
<input type="file" class="custom-file-input inputFile" id="inputFile" (change)="upload($event.target)" />
<label class="custom-file-label" for="inputFile">{{fileName}}</label>
</div>
</div>
<button class="btn btn-primary mt-2" (click)="passDAta()"> submit </button>


<div class="card-body">
<plotting [data]="data"></plotting>
</div>

container.ts文件:

data = new BehaviorSubject<any[]> ([]);
scanData: any = [];
upload(input: HTMLInputElement) {
const files = input.files;
const fileToRead = files[0];
if (fileToRead.type === "text/csv") {
this.fileName = fileToRead.name;
const fileReader = new FileReader();
fileReader.onload = event => {
const result = fileReader.result;
if (typeof result !== "string") {
throw new Error("Unexpected result from FileReader");
}
result.split("n").map(data => {
let [a, b] = data.split(",");
this.scanData.push(this.p2c(parseFloat(b), parseFloat(a)));
});
};
fileReader.readAsText(fileToRead, "UTF-8");
} else {
this.fileName = " unknow file type. csv only"
}
}
passDAta() {
this.data.next(this.scanData);
console.log("parent: ", this.scanData)
}

我的plotting component.ts是:

private _data: any; 
@Input()
set data(data: Observable<any>) {
data.subscribe(data => {
this._data = data;
});
}
get data () {
return this._data;
}

我也尝试过ngOnchanges。但无法检测到变化。我还创建了一个stackbliz。您可以下载csv1和csv2。如果您来回上传文件,您将看到数据不会从容器传递到绘图中。我该如何解决这个问题?

这是堆叠式

在这种情况下使用BehaviorSubject并不优雅,可能会导致订阅过多。您可以将data传递给setter,而不用担心更改检测。尝试以下

集装箱组件

data = [];
passDAta() {
this.data = this.scanData;
console.log("parent: ", this.scanData)
}

绘图组件

private _data: any; 
@Input()
set data(data: any) {
this._data = data;
}
get data () {
return this._data;
}

更新

变量scanData中的旧数据在推送新数据之前不会被删除。因此@Input()按预期工作,只是新数据被附加到旧数据的末尾。您可以在upload()函数的开头使用this.scanData = [];删除旧数据。尝试以下

upload(input: HTMLInputElement) {
this.scanData = [];
.
.
}

我修改了你的斯塔克布利茨。

我已经删除了Stacklitz中upload()函数中的CSV文件检查,以使其正常工作。如果没有,它会一直向我抛出未知的文件类型。"仅csv"错误。我还在绘图组件中为_data成员变量指定了类型Array<{'x': number, 'y': number}>

最新更新