为什么我的功能没有在区域中运行?

时间:2018-05-15 17:36:41

标签: angular

问题

我现在已经盯着这几个小时了,我不明白为什么我的最终功能没有在区域中运行。

我的功能顺序如下:

onFormSubmit() > getPhoneData() > getEligibility()

onFormSubmit()在区域中运行,但是当我们通过getPhoneData()函数时,我们不再在区域中运行。因此,当我将错误标志this.errored从false更新为true时,它会更新,并且可以记录为正确设置,但此更新不会反映在区域中。 只有当getPhoneDataFunction被强制发出数据HTTP请求时才会发生这种情况。你会注意到在这个函数中我强制它使用NgZone在区域中运行,但理想情况下我我不想这样做,因为我觉得这是一个黑客攻击。

onFormSubmit()

此功能是根功能。它首先调用getPhoneData(),它返回一个promise。然后它会在getElligibility()回调中调用.then()

onFormSubmit( event ): void {

  // Stop it, browser!
  event.preventDefault();
  event.stopPropagation();

  // Ok let's get the phone data
  this.getPhoneData().then( phoneData => {

    // Check the users elligibility
    this.getEligibility(phoneData);
  })
}

getPhoneData()

此函数返回一个promise并返回已检索的现有数据,或者进行HTTP调用以获取数据。

// Gets phone data and returns it
getPhoneData(): any {
  return Promise( (resolve, reject) => {

    // If we already have phone data
    if ( this.phoneData){

      // Resolve with the existing data
      resolve(this.phoneData);

    // Otherwise attempt to get the phone data
    } else {

      // We are now loading
      this.loading = true;

      // Create headers
      const headers = new Headers();

      // Create the authentication header
      headers.append(CENSORED);

      // Create the request options object
      const options = new RequestOptions({headers: headers});

      // Get the phone number information
      this.httpService.get(this.phoneDataUrl, options).subscribe( results => {

        // Get the phone number data from the results object, split on line returns and remove any empty strings
        this.phoneData = results.text().split(/\r?\n/g).filter( string => string.length );

        // We are no longer loading
        this.loading = false;

        // Resolve the promise
        resolve(this.phoneData);
      })
    }
  })
}

getEligibility()

此功能只是根据白名单数字检查用户输入的数字,并将错误标志this.errored设置为true,或者如果该数字符合条件,则执行其他任务。 这就是问题所在,当我在此时设置标志时,它会更新属性,但该更新不会反映在DOM中。

// Checks elligibility
getEligibility( phoneData: string[] ): void {

  // Get just the numbers from whatever the user input
  const cleanNumber = this.userPhoneNumber.replace(/[^0-9]/g, "");

  // Get whether the user is eligible or not
  const isEligible = phoneData.map( number => number === cleanNumber ).includes(true);

  // If the user is not eligible
  if ( !isEligible ){

    // Make sure this runs in the zone
    this.zone.run( () => {

      // Show the error state
      this.errored = true;
    });

  } else {

    // Do other stuff
  }
}

解决方案

有没有办法在区域中运行此功能以便DOM更新,或者这种“黑客”是完成工作的唯一方法吗?有人可以指点我的方向吗?

1 个答案:

答案 0 :(得分:1)

您可以更改代码,以便getPhoneData返回Observable而不是Promise。您可以在onFormSubmit订阅。

onFormSubmit( event ): void {
  event.preventDefault();
  event.stopPropagation();
  this.getPhoneData().subscribe(phoneData => {
    this.getEligibility(phoneData);
  });
}
getPhoneData(): Observable<any> {
  if (this.phoneData){
    return Observable.of(this.phoneData);
  } else {
    this.loading = true;
    const headers = new Headers();
    headers.append(CENSORED);
    const options = new RequestOptions({headers: headers});
    return this.httpService.get(this.phoneDataUrl, options)
      .do(results => {
        this.phoneData = results.text().split(/\r?\n/g).filter(string => string.length);
        this.loading = false;
      }
      .map(results => this.phoneData);
  }
}