Bagaimana cara menetapkan array ke properti objek dalam metode Angular Subscribe?

Aug 21 2020

Saya mencoba untuk mendapatkan nilai array dari file terjemahan en.json dalam bentuk sudut dan mencoba untuk mengikatnya ke properti objek seperti yang ditunjukkan di bawah potongan kode.

kode ketikan:

  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 file terlihat seperti ini:

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

Saya menggunakan layanan penerjemah ngx untuk mendapatkan data dari file en.json dan kemudian berlangganan dan menetapkan nilai ke properti dayNamesMin dari objek this.en.

Ketika saya mencatat nilai Object.keys (diterjemahkan) .map (key => diterjemahkan [key]); nilai di konsol, saya mendapatkan array yang tepat ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]. Tapi itu tidak mengikat ke properti objek dayNamesMin.

Bisakah seseorang membantu di sini?

Jawaban

1 MichaelD Aug 21 2020 at 21:53

Saat Anda berurusan dengan data asinkron menggunakan observable, lebih baik menetapkan nilai di dalam langganannya daripada percaya bahwa variabel akan ditetapkan saat diakses. Dalam kasus Anda, Anda dapat melakukan hal seperti berikut ini

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

Sekarang Anda memiliki gagasan bahwa this.envariabel tidak diberi nilai sampai yang this.translateSvc.get()dapat diamati dipancarkan. Jadi, Anda perlu ingat itu this.enasynchronous ketika diakses.

Info lebih lanjut tentang data asinkron di sini .


Atau katakan jika Anda hanya ingin menggunakan this.envariabel di template untuk menampilkan nilai, Anda dapat memetakan output this.translateSvc.get()menggunakan mapoperator RxJS dan menggunakan asyncpipa Angular .

Kontroler

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

Template

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

Pembaruan: Gunakan dengan kalender PrimeNg

Seperti yang ditunjukkan pada varian kedua, gunakan mapoperator RxJS untuk mengubahnya menjadi format objek yang diperlukan dan menggunakannya sebagai input di template 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>