我有一个Angular组件,该组件从服务器提取数据以填充下拉列表,并从路由中提取参数以设置下拉列表中的所选选项。这些都是在ngOnInit()中完成的。因为这两个都使用可观察变量,所以我的解决方案是否会出现争用条件,因此可以在填充选项之前设置下拉选择的值?
import { Component, OnInit } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, NgForm } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { ToastrService } from 'ngx-toastr';
import { ProjectService } from '../../shared/services/project.service';
@Component({
selector: 'app-project-status-form',
templateUrl: './project-status-form.component.html',
styleUrls: ['./project-status-form.component.scss']
})
export class ProjectStatusFormComponent implements OnInit {
projectShortName: string;
projectsShortName: string[];
projectStatusForm: FormGroup;
constructor(
private fb: FormBuilder,
private projectService: ProjectService,
private route: ActivatedRoute,
private toastr: ToastrService
) {
this.projectStatusForm = this.fb.group({
projectShortName: '',
statusText: '',
varianceOriginal: ''
});
}
ngOnInit(): void {
// Populate dropdown.
this.projectService.getProjectsShortName().subscribe((data) => this.projectsShortName = data);
// Set the selected value of the dropdown.
this.route.params.subscribe(params => {
this.projectShortName = params['projectShortName'];
const projectShortNameDropdownBox: AbstractControl = this.projectStatusForm.get('projectShortName');
if (this.projectShortName) {
projectShortNameDropdownBox.setValue(this.projectShortName);
projectShortNameDropdownBox.disable();
} else {
projectShortNameDropdownBox.enable();
}
});
}
}
<form #npsForm="ngForm" class="col-md-8" [formGroup]="projectStatusForm">
<div class="form-group">
<label for="projectShortName">Project</label>
<select id="projectShortName" class="form-control" formControlName="projectShortName" required>
<option *ngFor="let shortName of projectsShortName" [value]="shortName">{{shortName}}</option>
</select>
</div>
<div class="form-group">
<label for="statusText">Status Text</label>
<textarea id="statusText" class="form-control" formControlName="statusText" required rows="4"></textarea>
</div>
<div class="form-group">
<label for="varianceOriginal">Variance</label>
<input id="varianceOriginal" class="form-control" formControlName="varianceOriginal" required type="text">
</div>
</form>
答案 0 :(得分:1)
可能是比赛条件。通常,从API中提取数据比路由器花费更多的时间,但我仍然希望使用mergeMap避免竞争条件错误。您可以在下面的链接中查看示例mergeMap代码:
https://jsfiddle.net/btroncone/41awjgda/
//emit 'Hello'
const source = Rx.Observable.of('Hello');
//map to inner observable and flatten
const example = source.mergeMap(val => Rx.Observable.of(`${val} World!`));
//output: 'Hello World!'
const subscribe = example.subscribe(val => console.log(val));
答案 1 :(得分:0)
没有显式同步的多个异步操作总是 一个竞争条件。在这种情况下,出现竞争状况的可能性很低-因为一个操作涉及IO,而另一个操作不涉及IO-但您的实现不能保证顺序。
您可以使用flatMap()显式同步。另外,如果您的组件不是routed feature module,请考虑使用route snapshot;它是同步的。