【问题标题】:angular 2 wait for synchronous method角度2等待同步方法
【发布时间】:2016-08-25 09:45:29
【问题描述】:

我有 2 个下拉列表,我根据下拉列表 1 的值填充第二个下拉列表。我有场景可以根据网格编辑和填充下拉值。

private populateContacts(relationship: Relationship) {
        this.getContacts(relationship.businessAreaId);
        this.selectedContact = this.contacts.find(contact => contact.id === relationship.contacts[0].id);
    }

    private getContacts(businessAreaObjorId) {
        if (businessAreaObjorId === NaN)
            businessAreaObjorId = businessAreaObjorId.id;
        this.businessAreaService.getContacts(businessAreaObjorId)
            .subscribe(
            contacts => this.contacts = contacts,
            error => this.errorMessage = error);
    }

下面是HTML

<tr *ngFor="let relationship of relationships">
                <td>{{relationship.supplierName}}</td>
                <td>{{relationship.businessArea}}</td>
                <td>{{relationship.contacts[0].name}}</td>
                <td><a href="javascript:void(0)" (click)="onEdit(relationship)">Edit</a></td>
            </tr>
            <tr class="active">
                <td>
                    <select class="form-control" name="supplier" required
                            [(ngModel)]="selectedSupplier" #supplier="ngModel">
                        <option *ngFor="let supplier of suppliers" [ngValue]="supplier">{{supplier.name}}</option>
                    </select>
                    <div [hidden]="supplier.valid || supplier.pristine" class="alert alert-danger">
                        Supplier is required
                    </div>
                </td>
                <td>
                    <select class="form-control" name="businessArea" required
                            [(ngModel)]="selectedBusinessArea" #businessArea="ngModel" (ngModelChange)="getContacts($event)">
                        <option *ngFor="let businessArea of businessAreas" [ngValue]="businessArea">{{businessArea.name}}</option>
                    </select>
                    <div [hidden]="businessArea.valid || businessArea.pristine" class="alert alert-danger">
                        Business Area is required
                    </div>
                </td>
                <td>
                    <select class="form-control" name="contact" required
                            [(ngModel)]="selectedContact" #contact="ngModel">
                        <option *ngFor="let contact of contacts" [ngValue]="contact">{{contact.name}}</option>
                    </select>
                    <div [hidden]="contact.valid || contact.pristine" class="alert alert-danger">
                        Contact is required
                    </div>
                </td>
                <td>
                    <input type="button" value="Add" class="btn btn-default" (click)="onSubmit()" [disabled]="!factoryRelationshipForm.form.valid" />
                </td>
            </tr>

当我点击编辑链接时,onEdit 方法被调用并选择/分配值,但在选择联系人时失败。

private onEdit(relationship: Relationship): void {
    relationship.inEditMode = true;
    this.selectedSupplier = this.suppliers.find(supplier => supplier.id === relationship.supplierId);
    this.selectedBusinessArea = this.businessAreas
        .find(businessArea => businessArea.id === relationship.businessAreaId);
    this.populateContacts(relationship);
}

private populateContacts(relationship: Relationship) {
    this.getContacts(relationship.businessAreaId);
    this.selectedContact = this.contacts.find(contact => contact.id === relationship.contacts[0].id);
}

当我试图在联系人数组中查找联系人时,它上线失败。

我认为原因是 service.getcontacts 是 http 调用,它需要时间,当我试图在 this.contacts 数组中找到 undefined 的联系人对象时。

有没有办法在populateContacts方法中等待getContacts?

编辑 1:

我的新代码如下所示

private populateContacts(relationship: Relationship) {
        //TODO: find a way to use this.contacts/getContacts
        this.businessAreaService.getContacts(relationship.businessAreaId)
            .subscribe(val => {
                console.log(val);
                this.contacts = val;
                this.selectedContact = this.contacts.find(contact => contact.id === relationship.contacts[0].id)
            });
    }

private getContacts(businessAreaObj) {
    this.businessAreaService.getContacts(businessAreaObj.id)
        .subscribe(
        contacts => this.contacts = contacts,
        error => this.errorMessage = error);
}

编辑 2:

@Gunter' 解决方案适用于编辑案例,但如果我在 BA 上手动选择下拉值,它不会在联系人下拉列表中加载联系人。

【问题讨论】:

  • 能否请您显示您的编辑按钮的 html 代码?
  • 请检查更新html的问题

标签: angular typescript promise


【解决方案1】:

您需要返回Observable。为此,您不得致电subscribe()

private getContacts(businessAreaObjorId) {
    if (businessAreaObjorId === NaN)
        businessAreaObjorId = businessAreaObjorId.id;
    return this.businessAreaService.getContacts(businessAreaObjorId)
        .catch(error => this.errorMessage = error)
        .map(
        contacts => this.contacts = contacts);

    }
}

然后你可以调用它,获取一个可以订阅的Observable,并在回调中调用后续代码:

private populateContacts(relationship: Relationship) {
    this.getContacts(relationship.businessAreaId)
    .subscribe(val => this.selectedContact = this.contacts.find(contact => contact.id === relationship.contacts[0].id));
}

【讨论】:

  • 感谢您的回复 Gunter,this.businessAreaService.getContacts 已经可以观察到。它是一个http调用。我这里有 2 个场景。 1. 根据 BA 值填充联系人下拉列表 2. 单击编辑时选择值。对于第一种情况,我不需要可观察的。就像我在两种情况下都调用相同的方法一样。但让我先试试你的解决方案:)
  • 正如预期的那样,上述解决方案非常适合编辑案例,但是当我创建新记录并从 BA 中选择值时,它不会填充联系人下拉列表,因为我没有订阅更改...我认为 getContacts 应该订阅并在填充联系人中我将直接调用该服务?我试图避免另一个 http 调用并使用相同的数组 this.contacts。有办法吗?
  • 了解所有这些细节有点复杂。听起来像stackoverflow.com/questions/36271899/…
  • 对不起,奇怪的解释。当我调用 getcontacts() 时,我将数组分配给 this.contacts。我只想在 populateContacts() 方法中使用相同的数组。
  • 来自getContactscontacts 被转发给订阅者。 val in populateContacts() 将是同一个数组(从.map(contacts =&gt; this.contacts = contacts) 返回的那个(this.contacts = contacts 的结果将是contacts
猜你喜欢
  • 2018-07-08
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多