使用observables通过单个http调用更新多个组件属性

时间:2016-09-08 15:47:21

标签: angular rxjs observable

上一篇文章相关: Angular2 : Reduce number of Http calls

上下文仍然是相同的:我正在尝试设置一个“dico”组件,需要输入ID和语言,并且应该从我的数据库中提供一些翻译后的文本。

dico.component.ts:

@Component({
    selector: 'dico',
    template: `{{text}}`  // => The text I'm trying to update
})

class Dico implements AfterViewInit {
    // Définition des paramètres et du texte en sortie
    @Input() private dicoID: string;
    @Input() private dicoLang: string;
    public text: string = null;

    constructor(private dicoService: DicoService) {
    }

    (...)
}

@Component({
    template: `<dico [dicoID] [dicoLang]></dico>`,
    directives: [Dico]
})

export class DicoComponent {

}  

在HTML文件中的使用:

<dico [dicoID]="dicoService.getDico('211800', 'en') | async"></dico>
<dico [dicoID]="dicoService.getDico('211801', 'en') | async"></dico>

在.ts中使用以下代码:

ngAfterViewInit() {
    this.dicoService.sendRequest();
}

我正在调用“dicoService”来订阅这些“dico”,然后将resquest发送到我的API,成功地为我提供了结果:

dico.service.ts:

@Injectable()
export class DicoService {
    private subjects = []
    private ids: string[] = [];

(...)

getDico(id: string, lang: string): Observable<DicoComponent> {

    if (id != null) {
        let singleSubject = this.subjects[id];

        if (!singleSubject) {
            this.ids.push(id);
            singleSubject = new Subject();
            this.subjects[id] = singleSubject;
        }
        return singleSubject.asObservable().share().take(1);
    }
}

sendRequest() {
    // Stuff to call the ASP Controller that calls the API 
    (...)        

    this.http.get(lControllerFullURL + lHttpRequestBody)
        .map((res: any) => res.json())
        .subscribe(data => {
            // Gestion du retour du WebService
            switch (data.status) {
                case "success":
                    let l_cRet: string = null;

                    // Response is looking like that : {"status":"success",
                    //                                  "results"://{"211800":"Compétences obligatoires",
                                                                   "211801":"Toutes les compétences"}}
                    for (l_cRet in data.results) {
                        let l_dicoID = l_cRet;                   // My DicoID
                        let l_dicoText = data.results[l_cRet];   // the text

                        if (!l_dicoText.includes("UNDEFINED")) {
                            // Trying to send the text to the corresponding dicoID here
                            this.subjects[l_dicoID].next(l_dicoText);
                        }
                        else {
                             (...)
                        }

                    }
                    break;
                (...)
            }
        });
}

N.B:我注意到两件事:

  1. 我没有错误,但我需要更多内容来更新我的dico文本
  2. 我可能需要.complete()我的observable,但我真的不知道什么时候。
  3. 我是RxJS的小伙伴,我需要更多时间来理解它们,所以请耐心等待我......

1 个答案:

答案 0 :(得分:1)

我不知道究竟是什么问题,但我会像

那样更改组件
  @Component({
    selector: 'dico',
    template: `{{text | async}}`  
  })

  class Dico implements OnChanges {
    // Définition des paramètres et du texte en sortie
    @Input() private dicoID: string;
    @Input() private dicoLang: string;
    public text: Observable<String> = null;

    constructor(private dicoService: DicoService) {}

    ngOnChanges() {
      if(dicoId && dicoLang) {
        this.text = dicoService.getDico('211800', 'en');
      }
    }
  }

然后您可以将其与

一起使用
<dico dicoID="211800" lang="en"></dico>

或