Angular2异步调用

时间:2016-10-24 10:33:47

标签: asynchronous angular

我面临着经典的http竞赛问题,但我对Angular2和Observable不够熟悉,无法解决我的问题。

这是我的砖块的描述:

[ FormComponent ]
    |    |
   1|    |6
    |    |
[ MetadataService ] <----4 & 5----> [ TranslatorService ]
    |    |
   2|    |3
    |    |
 [ Backend ]
  1. 我的表单组件向MetadataService询问表单
  2. 的元数据
  3. Metadataservice对后端进行HTTP调用以检索这些元数据
  4. Backend以JSON格式返回元数据
  5. MetadataService将JSON传输到TranslatorService
  6. TranslatorService在JSON中进行一些翻译并将数组返回到MetadataService
  7. MetadataService将数组返回给FormComponent。
  8. 架构看起来很简单,但我实现这一点的方式有问题,因为在我看来,元数据属性是&#34;未定义&#34;因此* ngFor会抛出错误 我的第一个想法是订阅组件中的Observable,但我不知道如何处理这些Observable,因为我有两项服务。

    从我看来,问题来自第四步:

    MetadataService

    getFormMetaData(folderId: string, context: string){
        let body = JSON.stringify({
                       folderId: folderId,
                       context: context
                   });
        return this.http.post(this.uri, body, options)
                                .map( (res) => { 
                                        let body = res.json();
                                        if (body.data){
                                            return this.translatorService.getTranslatedElements(body.data);
                                        }
                                    } 
                                );
    }
    

    它应该返回一个Observable,但map()方法返回TranslatorService的值,这是一个数组......

    我该怎么办?

    编辑: 这是我的FormComponent:

    FormComponent

    @Component({
        template: `
            <dynamic-form controls="formMetadata | async"></dynamic-form>
        `,
        providers: [MetadataService]
    })
    export class CustomerFormComponent {
    
        formMetadata: any; 
    
        constructor(private metadataService: MetadataService) { }
    
        ngOnInit() {
            this.formMetadata = this.formMetadataService.getFormMetadata('FR75P00000012', 'UserInformation');
        }
    }
    

    我的翻译服务:

    TranslatorService

    getTranslatedElements(metadata: any) {
        debugger; // It never breaks here
        let elements = [];
    
        metadata.forEach( (field) => { 
            ...
            elements.push(field);
        } ) 
    
        return elements;
    
    }
    

    更新:

    好的,我进步了一下。似乎问题来自我的异步管道,我在FormComponent模板中使用它来将数据传递给子组件。

    此子组件是否也应以特定方式处理此类异步数据?

    解决方案 如何浪费时间进行调试:忘记将数据绑定属性放在括号内。

    <dynamic-form controls="formMetadata"></dynamic-form>

    应该是

    <dynamic-form [controls]="formMetadata"></dynamic-form>

    这就解释了为什么DynamicFormComponent收到一个字符串作为输入......

    解决方案2 实际上,我仍然遇到了在订阅功能加载数据之前使子组件实例化的问题。 我通过做一个来解决这个问题 <dynamic-form [controls]="formMetadata" *ngIf="formMetadata"></dynamic-form>

    我无法使用异步管道,但它无法正常工作。我不知道父模板中的异步触发器何时触发,但它似乎在子组件构造函数()和noOnInit()之后

1 个答案:

答案 0 :(得分:0)

http://reactivex.io/documentation/operators/map.html

中所述
  

Map运算符将您选择的函数应用于每个项目   由源Observable发出,并返回发出的Observable   这些功能应用的结果。

所以MetadataService应该返回一个返回this.translatorService.getTranslatedElements(body.data);的Observable 或者,如果body.data为空,则Observable为undefined。