Заставить функцию возвращать значение для привязки свойства после загрузки асинхронных данных

<cv-radio-button-group class="duration-radios" 
    [radioItems]="getRadioButtons()" 
</cv-radio-button-group>

Так что у меня есть этот угловой 2 компонента <cv-radio-button-group> которая представляет собой специальную группу переключателей. Количество переключателей определяется свойством [radioItems], Это все работает очень хорошо в среде синхронизации.

Но сейчас я внедряю его в проект с вызовами на сервер, и теперь он находится в асинхронной среде. Таким образом, при запуске getRadionButtons() функция вызывается, пока вызов на сервер все еще делает свое дело. А также getRadiobuttons() нужны данные с сервера, чтобы вернуть правильное количество переключателей, поэтому я не получаю правильный результат.

Я могу заставить его щелкнуть где-нибудь еще и щелкнуть назад, заставив ngOnInit() работать.

Есть ли способ заставить функцию возвращать ее снова, когда асинхронные данные закончены?

2 ответа

Решение

Существует как минимум 3 различных подхода, которые вы можете использовать, но похоже, что вы ищете подход с полным DOM, который возможен при использовании *ngIf,

Для вашей группы кнопок вы можете фактически сделать логическое утверждение с вашей функцией, чтобы проверить состояние возврата перед рендерингом, обратите внимание, что <ng-container> на самом деле не производит и DOM:

<ng-container *ngIf="getRadioButtons() && getRadioButtons().length>
  <cv-radio-button-group class="duration-radios" 
    [radioItems]="getRadioButtons()" 
   </cv-radio-button-group>
</ng-container>

В приведенном выше коде логическое состояние ожидает, что сначала getRadioButtons() вернет элемент, и (при условии, что его возвращение будет массивом), а затем убедитесь, что массив заполнен перед рендерингом.

Как упомянуто в комментариях, обычно этот тип проверки лучше всего реализовывать в вашем компоненте и / или службе машинописи с использованием Observables (или Promise). The Angular: Tour of Heroes - Http освещает это хорошо и подробно.

Пример обещания:

const promise =
  new Promise((resolve, reject) => {
  // do some async stuff

  if (CONDITION) resolve(DATA);
  else reject(ERROR);
  })
  .then(
  (data) => { console.log(data); },
  (err) => { console.log(err); }
  );

Для вашего примера в вашей машинописи component.ts вы бы добавили машинописный текст так:

radioData: any;
isLoaded: false;

getRadioButtons {
  const promise = new Promise((res, rej) => {
    // ... previous radioButtons code ... ends with data.
    res(radioButtonsData) // this sends the data to the promise handlers below
  })
  .then((data) => { this.radioData = data; this.isLoaded = true; })

И вы бы либо использовать *ngIf="isLoaded" или вместо этого вы можете просто использовать асинхронный канал.

Для отличного детального использования примера обещаний и более продвинутого уровня воспользуйтесь этой ссылкой и перейдите в раздел "Напишите свое первое обещание".

Почему ты не звонишь getRadioButtons() в ngOnInit() а затем назначить результаты [radioItems],

При условии, что getRadioButtons() вернется наблюдаемый.

public radioCount;

ngOnInit() {
       this.getRadioButtons().subscribe(
          (data) => {
            this.radioCount = data;
      });
}

.html

<div *ngIf="radioCount">
   <cv-radio-button-group class="duration-radios" 
        [radioItems]="radioCount" 
   </cv-radio-button-group>
</div>
Другие вопросы по тегам