AngularSubscribeメソッドでオブジェクトプロパティに配列を割り当てる方法は?

Aug 21 2020

以下のコードスニペットに示すように、角度でen.json変換ファイルから配列値を取得し、それをオブジェクトプロパティにバインドしようとしています。

タイプスクリプトコード:

  ngOnInit() {
    this.en = {
      dayNamesMin: this.translateSvc
                  .get(['calendar.day_names_min.Sun', 'calendar.day_names_min.Mon', 'calendar.day_names_min.Tue', 'calendar.day_names_min.Wed',
                    'calendar.day_names_min.Thu', 'calendar.day_names_min.Fri', 'calendar.day_names_min.Sat'])
                  .subscribe(translated => {
                    console.log(Object.keys(translated).map(key => translated[key]));
                    return Object.keys(translated).map(key => translated[key]);
                  })
    };
  };

en.jsonファイルは次のようになります。

{
    "calendar" : {
        "day_names_min": {
            "Sun": "SUN",
            "Mon": "MON",
            "Tue": "TUE",
            "Wed": "WED",
            "Thu": "THU",
            "Fri": "FRI",
            "Sat": "SAT"
        }
    }
}

ngxトランスレータサービスを使用してen.jsonファイルからデータを取得し、サブスクライブしてthis.enオブジェクトのdayNamesMinプロパティに値を割り当てています。

値をログに記録するとObject.keys(translated).map(key => translation [key]); コンソールの値、適切な配列["SUN"、 "MON"、 "TUE"、 "WED"、 "THU"、 "FRI"、 "SAT"]を取得しています。ただし、オブジェクトプロパティdayNamesMinにはバインドされていません。

誰かがここで助けてくれますか?

回答

1 MichaelD Aug 21 2020 at 21:53

オブザーバブルを使用して非同期データを処理する場合は、アクセス時に変数が割り当てられることを信頼するのではなく、サブスクリプション内で値を割り当てることをお勧めします。あなたの場合、あなたは次のようなことをすることができます

ngOnInit() {
  this.translateSvc.
    .get([
      'calendar.day_names_min.Sun', 
      'calendar.day_names_min.Mon', 
      'calendar.day_names_min.Tue', 
      'calendar.day_names_min.Wed',
      'calendar.day_names_min.Thu', 
      'calendar.day_names_min.Fri', 
      'calendar.day_names_min.Sat'
    ])
    .subscribe(translated => {
      this.en = {
        dayNamesMin: Object.keys(translated).map(key => translated[key])
      };
    });
}

これでthis.enthis.translateSvc.get()オブザーバブルが放出されるまで変数に値が割り当てられないことがわかりました。したがって、this.enアクセス時に非同期であることを覚えておく必要があります。

非同期データの詳細については、こちらをご覧ください。


またはthis.en、テンプレート内の変数のみを使用して値を表示する場合は、this.translateSvc.get()RxJSmap演算子を使用して出力をマッピングし、Angularasyncパイプを使用できます。

コントローラ

en$: Observable<any>; ngOnInit() { this.en$ = this.translateSvc.     // <-- assign the observable
    .get([
      'calendar.day_names_min.Sun', 
      'calendar.day_names_min.Mon', 
      'calendar.day_names_min.Tue', 
      'calendar.day_names_min.Wed',
      'calendar.day_names_min.Thu', 
      'calendar.day_names_min.Fri', 
      'calendar.day_names_min.Sat'
    ])
    .pipe(       // <-- transform the response here
      map(translated => ({ dayNamesMin: Object.keys(translated).map(key => translated[key]) }))
    );
}

テンプレート

<ng-container *ngIf="(en$ | async) as en">
  {{ en.dayNamesMin | json }}
  {{ en.dayNamesMin[0] }}
  ...
  <p *ngFor="let day of en.dayNamesMin">
    {{ day }}
  </p>
</ng-container>

更新:PrimeNgカレンダーで使用

2番目のバリアントに示されているように、RxJSmap演算子を使用して必要なオブジェクト形式に変換し、HTMLテンプレートの入力として使用します。

<ng-container *ngIf="(en$ | async) as en">
  <p-calendar 
    dateFormat="dd/mm/yy" 
    [(ngModel)]="value" 
    [locale]="en">   <!-- use `en` from the async pipe -->
  </p-calendar>
</ng-container>