加载异步数据后强制函数为 属性 绑定的 return 值

Force a function to return value for property binding after async data is loaded

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

所以我有这个 angular 2 组件 <cv-radio-button-group>,这是一个定制的单选按钮组。单选按钮的数量由 属性 [radioItems] 决定。这一切在同步环境中都非常有效。

但现在我通过调用服务器在项目中实现它,现在它处于异步环境中。 所以在启动时调用 getRadionButtons() 函数,而此时对服务器的调用仍在执行它的操作。 getRadiobuttons() 需要服务器的数据 return 正确数量的单选按钮,所以我没有得到正确的结果。

我可以通过单击其他地方然后单击返回来强制它,强制 ngOnInit() 到 运行。

有没有办法在异步数据完成后强制函数再次return它?

您至少可以采用 3 种不同的方法,但听起来您正在寻找一种完整的 DOM 方法,这可以通过使用 *ngIf.

对于你的按钮组,你实际上可以用你的函数做一个逻辑语句来在渲染之前检查 return 的状态,请注意 <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() 到 return 一个项目,并且(假设它是 return 将是一个数组)然后确保该数组被填充渲染之前。

如评论中所述,通常这种类型的检查最好在使用 Observables(或 Promise)的打字稿组件 and/or 服务中实现。 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" 或者你可以简单地使用 async pipe.

有关 promise 的优秀详细使用示例和更高级的使用,请查看 this link 并转到 "Write your first promise".

部分

为什么不在ngOnInit()中调用getRadioButtons(),然后将结果赋值给[radioItems]

假设 getRadioButtons() 将 return 可观察。

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>