Angular - см. Изменение переменной в родительском компоненте

В основном у меня есть форма, которая является родительским компонентом. Эта форма состоит из дочернего компонента.

Чтобы отключить кнопку, я проверяю переменную (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>

Рассматривали ли вы использование темы для связи между компонентами?

jburtondev 06.07.2018 22:33

Что вы имеете в виду под темой? Нравится общий сервис?

PierBJX 06.07.2018 22:35

Точно. Если в этом случае трудно использовать декоратор ввода, то использование общей службы, такой как (в официальной документации Angular): angular.io/guide/…, позволит вам сделать это с большим контролем.

jburtondev 06.07.2018 22:38

Да, я знаю, что уже использую службу для некоторой переменной, но я хотел знать, есть ли другой способ вместо создания переменной переменной в моей общей службе

PierBJX 06.07.2018 22:40

Это кажется излишне сложным. Для того, что вам нужно, будет достаточно декоратора ввода или межкомпонентной связи через службу. Вы просто пытаетесь позволить компоненту обнаруживать изменение переменной в другом компоненте, верно?

jburtondev 06.07.2018 22:44

Да, точно! Но что странно, это работает, если его нет в обратном вызове

PierBJX 06.07.2018 22:53

Позвольте нам продолжить обсуждение в чате.

jburtondev 06.07.2018 22:56

@PierBJX Не могли бы вы показать, какая строка кода не работает?

Uğur Dinç 06.07.2018 23:05

В дочернем компоненте. Когда строка имеет вид this.datasetList [index] .fileValid = true; Это работает, но не учитывается родительским компонентом. Но если эта строка находится за пределами обратного вызова, она работает

PierBJX 06.07.2018 23:25

@PierBJX Вы видите ошибки в консоли?

Uğur Dinç 06.07.2018 23:30

Нет, ошибки нет. Я думаю, это связано с крючками жизненного цикла. Это не ошибка. Просто обратный вызов завершается после onChange ()

PierBJX 06.07.2018 23:34
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
11
65
1

Ответы 1

Поскольку ваше изменение отслеживается родителем, когда изменение происходит вне обратного вызова, но не изнутри, это может быть проблемой с контекстом.

Попробуй это:

  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);
  }

Другие вопросы по теме