angular - 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。如果您来回上传文件,您会看到,数据不会从容器传递到绘图中。我该如何解决这个问题?
这是堆栈闪电战
解决方案
在这种情况下使用 aBehaviorSubject
并不优雅,可能会导致订阅过多。您可以只传递data
to 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()
按预期工作,除了新数据被附加到旧数据的末尾。您可以在函数this.scanData = [];
开头使用删除旧数据。upload()
尝试以下
upload(input: HTMLInputElement) {
this.scanData = [];
.
.
}
我已经修改了您的Stackblitz。
我已删除upload()
Stackblitz 函数中的 CSV 文件检查以使其正常工作。如果没有,它会一直向我抛出“未知文件类型”。仅 csv' 错误。我还将类型分配给绘图组件Array<{'x': number, 'y': number}>
中的_data
成员变量。
推荐阅读
- scala - Scala中cats.effect的IO.async回调问题
- php - 如何使用femanager (TYPO3) 进行更新?
- three.js - Threejs中的灯光和颜色不一致
- c# - 在 ASP.NET Core MVC (C#) 中禁用其他表单输入
- html - 为 Outlook 电子邮件格式化 HTML 表格中的单元格
- python - 如何使用 cython 将 python 脚本导入模块编译为可执行文件
- tkinter - 带有图像的选项菜单的 Tkinter 更新按钮
- python - 如何将列表列表的字符串转换为列表?
- php - 使用优惠券时自动完成订单。WooCommerce
- sqlite - 查询以比较 SQLITE 中同一表中的两行