如何在Angular Subscribe方法中为对象属性分配数组? 更新:与PrimeNg日历一起使用

问题描述

我正在尝试从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 => translationd [key]); 时,我正在获取正确的数组[“ SUN”,“ MON “,” TUE“,” WED“,” THU“,” FRI“,” SAT“]。但是它没有绑定到对象属性dayNamesMin。

有人可以在这里帮忙吗?

解决方法

当您使用可观察对象处理异步数据时,最好在预订的内部分配值,而不是相信在访问变量时将分配该值。就您而言,您可以执行以下操作

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.en可观察变量,才为this.translateSvc.get()变量赋值。因此,您需要记住this.en在访问时是异步的。

有关异步数据here的更多信息。


或者说,如果您只想使用模板中的this.en变量来显示值,则可以使用RxJS map运算符映射来自this.translateSvc.get()的输出并使用Angular {{ 3}}管道。

控制器

en$: Observable<any>;

ngOnInit() {
  this.en$ = this.translateSvc.     // <-- assign the observable
    .get([
      'calendar.day_names_min.Sun','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日历一起使用

如第二个变体所示,使用RxJS map运算符将其转换为所需的对象格式,并将其用作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>