В основном у меня есть форма, которая является родительским компонентом. Эта форма состоит из дочернего компонента.
Чтобы отключить кнопку, я проверяю переменную (datasetList [i] .fileValid) с помощью функции isDatasetFilesValid (). В дочернем компоненте изменяется переменная.
Однако это изменение выполняется в обратном вызове, когда я анализирую файл с помощью papaparse, и поскольку это выполняется в обратном вызове, родитель не видит его. Я знаю это, потому что, если я изменяю переменную вне обратного вызова, кнопка становится доступной.
Эта переменная проверяется, чтобы убедиться, что файл выбран.
Поэтому я попытался добавить «detectChanges ()», но это не сработало.
Родительский компонент:
export class ExperimentCreateComponent implements OnInit {
datasetList: any = [{ fileValid: false }];
isDatasetFilesValid() {
let index = this.datasetList.findIndex(function(item, i) {
return item.fileValid == false;
});
let test = index === -1 ? true : false;
console.info("Dataset", index + " -> " + test);
return test;
}
}
Родительский HTML:
<div class = "jumbotron">
<div class = "container">
<div class = "row">
<div class = "col-sm-8 offset-sm-2">
<form name = "form" (ngSubmit) = "f.form.valid" #f = "ngForm" novalidate>
<app-creation-dataset [datasetList] = "datasetList"></app-creation-dataset>
<button mat-button color = "primary" type = "submit" [disabled] = "!isDatasetFilesValid()" (click) = "createExperiment()">Submit</button>
</form>
</div>
</div>
</div>
</div>
Дочерний компонент:
export class CreationDatasetComponent implements OnInit {
@Input() datasetList: any = [{ fileValid: false }];
fileSelected: File;
constructor(private papa: Papa, private cd: ChangeDetectorRef) {}
ngOnInit() {}
onChange(files: FileList, index: number, dom: any) {
// Option to parse the file with papaparse
let options = {
header: true,
error: (err, file) => {
this.datasetList[index].fileValid = false;
alert(
"Unable to parse CSV file, please verify the file can be accessed and try again. Error reason was: " +
err.code
);
return;
},
complete: (results, file) => {
console.info("Parsed:", results, file);
let filename = file.name;
// Add the dataset to the datasetList
this.datasetList[index].headers = results.meta.fields;
this.datasetList[index].values = results.data;
this.datasetList[index].filename = filename;
this.datasetList[index].is_metadata = false;
this.datasetList[index].fileValid = true;
this.cd.detectChanges();
}
};
this.fileSelected = files[0]; // Get the file
// Call the function to parse the file, option is the callback
this.papa.parse(this.fileSelected, options);
}
}
Дочерний HTML:
<div *ngFor = "let dataset of datasetList; let index = index">
<div id = "datasetFiles">
<h6>Select the type of dataset and browse the files:</h6>
<div class = "container">
<div class = "row justify-content-between">
<div class = "col-6 d-flex align-items-center">
<input id = "file" #file (change) = "onChange(file.files, index, $event.currentTarget)" type = "file">
</div>
</div>
</div>
</div>
</div>
<div>
Что вы имеете в виду под темой? Нравится общий сервис?
Точно. Если в этом случае трудно использовать декоратор ввода, то использование общей службы, такой как (в официальной документации Angular): angular.io/guide/…, позволит вам сделать это с большим контролем.
Да, я знаю, что уже использую службу для некоторой переменной, но я хотел знать, есть ли другой способ вместо создания переменной переменной в моей общей службе
Это кажется излишне сложным. Для того, что вам нужно, будет достаточно декоратора ввода или межкомпонентной связи через службу. Вы просто пытаетесь позволить компоненту обнаруживать изменение переменной в другом компоненте, верно?
Да, точно! Но что странно, это работает, если его нет в обратном вызове
Позвольте нам продолжить обсуждение в чате.
@PierBJX Не могли бы вы показать, какая строка кода не работает?
В дочернем компоненте. Когда строка имеет вид this.datasetList [index] .fileValid = true; Это работает, но не учитывается родительским компонентом. Но если эта строка находится за пределами обратного вызова, она работает
@PierBJX Вы видите ошибки в консоли?
Нет, ошибки нет. Я думаю, это связано с крючками жизненного цикла. Это не ошибка. Просто обратный вызов завершается после onChange ()



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Поскольку ваше изменение отслеживается родителем, когда изменение происходит вне обратного вызова, но не изнутри, это может быть проблемой с контекстом.
Попробуй это:
onChange(files: FileList, index: number, dom: any) {
var that = this; // outer context
// Option to parse the file with papaparse
let options = {
header: true,
error: (err, file) => {
this.datasetList[index].fileValid = false;
alert(
"Unable to parse CSV file, please verify the file can be accessed and try again. Error reason was: " +
err.code
);
return;
},
complete: (results, file) => {
console.info("Parsed:", results, file);
let filename = file.name;
// Add the dataset to the datasetList
this.datasetList[index].headers = results.meta.fields;
this.datasetList[index].values = results.data;
this.datasetList[index].filename = filename;
this.datasetList[index].is_metadata = false;
that.datasetList[index].fileValid = true; // changed this to that
this.cd.detectChanges();
}
};
this.fileSelected = files[0]; // Get the file
// Call the function to parse the file, option is the callback
this.papa.parse(this.fileSelected, options);
}
Рассматривали ли вы использование темы для связи между компонентами?