【问题标题】:Ionic 5 / Angular 8 - Casting problem from any to my custom typeIonic 5 / Angular 8 - 从任何到我的自定义类型的转换问题
【发布时间】:2023-04-06 13:24:02
【问题描述】:

在我的 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 周围制作了一个 switch case 来修复它:

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

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

提前致谢!

【问题讨论】:

  • 你不需要 case 'nl': this.selectedLanguage = 'nl';休息;但也要记住它区分大小写

标签: angular typescript ionic-framework angular8 ionic5


【解决方案1】:

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

您的初始代码:

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' 字符串值。

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

这是一个很好的例子 from MDN 在你的控制台中展示了变量获得的初始值是未解决的(待定)承诺:

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 中的开发工具)中即可查看发生了什么。

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

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

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

【讨论】:

  • 这并不能解决我的问题。即使在使用 .then 的异步解决方案之后,三个语言按钮仍然存在。
  • 嗯,你能分享一下你是如何初始化值 selectedLanguages 的吗?基于到目前为止共享的代码,唯一一个解释为什么它不能解决你的问题可能是存储可能存储了一个空值。我将更新代码以反映这一点。
  • 基本上我添加了检查从存储中检索到的值是否为真,并且只有在这样的情况下才应用它。如果可以,请添加 console.logs 并分享此属性(selectedLanguage)在您的应用启动期间的值更改。
  • 添加了 stackblitz 仅供参考。看看,我玩了不同的条件并添加了||后备和代码似乎按您期望的方式工作。
最近更新 更多