0

在我的 Ionic 5 项目中,我遇到了以下问题:我认为我有一个铸造问题。在我看来,我只想在 selected-language 属性与语言本身不匹配时才显示语言标志图标。问题是,第一次启动应用程序时会显示所有三个图标!

我有以下看法:

<ion-toolbar color="secondary">
    <div class="flags">
      <ion-buttons slot="end" *ngIf="!loading">
        <ion-button *ngIf="selectedLanguage != 'de'" fill="clear" color="dark"
          class="ion-no-padding button-padding flag" (click)="changeLanguage('de')">
          <ion-icon src="../../../assets/flag-icons/de.svg"></ion-icon>
        </ion-button>
        <ion-button *ngIf="selectedLanguage != 'en'" fill="clear" color="dark"
          class="ion-no-padding button-padding flag" (click)="changeLanguage('en')">
          <ion-icon src="../../../assets/flag-icons/en.svg"></ion-icon>
        </ion-button>
        <ion-button *ngIf="selectedLanguage != 'nl'" fill="clear" color="dark"
          class="ion-no-padding button-padding flag" (click)="changeLanguage('nl')">
          <ion-icon src="../../../assets/flag-icons/nl.svg"></ion-icon>
        </ion-button>
      </ion-buttons>
    </div>
  </ion-toolbar>

在设置服务中,我使用以下函数从本地存储中获取语言字符串:

async getSetting(type: string) {
    let result;
    try {
      result = await this.storage.get('_setting_' + type);
    } catch (error) {
      console.warn(error);
    }
    return result;
  }

在我看来,我想设置选定的语言:

export type AcceptedLanguage = 'de' | 'en' | 'nl';

在我的页面组件中,我声明并初始化 selectedLanguage 如下:

selectedLanguage: AcceptedLanguage = 'de';

ngOnInit 定义如下:

async ngOnInit() {
    this._loading$ = this.loadingIndicationService.loading$.subscribe(
      (loading) => {
        console.log('loading subscribed in startscreen');
        this.loading = loading;
      }
    );

    this.selectedLanguage = await this.settingsService.getLanguage();

  }

我已经通过在 lang 周围制作一个开关盒来修复它,如下所示:

async ngOnInit() {
    this._loading$ = this.loadingIndicationService.loading$.subscribe(
      (loading) => {
        console.log('loading subscribed in startscreen');
        this.loading = loading;
      }
    );

    const lang = await this.settingsService.getLanguage();

    switch (lang) {
      case 'de':
        this.selectedLanguage = 'de';
        break;
      case 'en':
        this.selectedLanguage = 'en';
        break;
      case 'nl':
        this.selectedLanguage = 'nl';
        break;
      default:
        this.selectedLanguage = 'nl';
        break;
    }
  }

但这不是一个好的解决方案!对此有什么好的解决方案?为什么我们会有这个问题?为什么开关盒能解决这个问题?

提前致谢!

4

1 回答 1

0

这就是为什么在您的第一个案例中显示所有 3 个 *ngIf 条件模板,然后为什么切换案例“修复它”:

您的初始代码:

async ngOnInit() {
    this._loading$ = this.loadingIndicationService.loading$.subscribe(
      (loading) => {
        console.log('loading subscribed in startscreen');
        this.loading = loading;
      }
    );

    this.selectedLanguage = await this.settingsService.getLanguage();

  }

您的代码最初使用默认值 ('de') 初始化了“selectedLanguage”,如果没有尝试通过 Promise 从存储中读取 - 您只会看到 3 个模板中的 2 个。

问题是,在上述代码中,“selectedLanguage”在从存储中检索数据后被分配了一个 Promise 挂起解决方案。

并且未解决的待处理 Promise 不再等于 'de' 字符串值。

在您的切换案例中,您正在使用变量“lang”并等待 Promise 被解析为实际字符串,然后才将其分配给属性“selectedLanguage”,这可以防止问题,因为 selectedLanguage 保持为“de”,直到 promise 是完全解决。

这是来自 MDN的一个很好的示例,在您的控制台中演示了变量获得的初始值是未解决的(待处理的)Promise:

function resolveAfter2Seconds(x) { 
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function f1() {
  var x = await resolveAfter2Seconds(10);
  console.log(x); // initially returns Promise pending, then 10
}

f1();

只需将其粘贴到您的控制台(Chrome 中的 devtools)中即可查看发生了什么。

因此,如果您只在以这种方式解析后分配值,那么您的初始代码也可以:

async ngOnInit() {
    this._loading$ = this.loadingIndicationService.loading$.subscribe(
      (loading) => {
        console.log('loading subscribed in startscreen');
        this.loading = loading;
      }
    );

    this.settingsService.getLanguage().then(selectedLanguage => {
        if (selectedLanguage) {
            this.selectedLanguage = selectedLanguage;
        }
    })

  }

更新:

我试图在这里重新创建您的用例:https ://stackblitz.com/edit/ionic-angular-v5-ab6d6y

我怀疑在您的代码中可能有其他事情会阻止您想要的行为。随意玩耍。

于 2020-03-25T16:28:43.970 回答