我在Angular 2中创建了一个表单,用户可以使用该表单编辑SearchProfile
,他们可以从列表中进行选择。最初一切正常但是当我从SearchProfile
列表中选择一个不同的项时,我收到以下异常:
There is no FormControl instance attached to form control element with name: controlName
。
整件事由3个元素组成:2个组件SelectProfileComponent
,SearchProfileComponent
和服务ProfileService
。 ProfileService
包含ActiveProfile
,它是选定的SearchProfile
进行编辑。
ProfileService
看起来像这样:
@Injectable()
export class ProfileService {
private activeProfileSource = new ReplaySubject<ISearchProfile>();
activeProfile$ = this.activeProfileSource.asObservable();
constructor(private http: Http) {
this.selectProfile();
}
public getSearchProfile(profileId: number = null): Observable<ISearchProfile> {
let url = `<url>?profileid=${profileId}`;
this.http.get(url).map((result) => {
return <ISearchProfile>.result.json();
});
}
public selectProfile(profileId: number = null) {
this.getSearchProfile(profileId).subscribe((p) => {
this.activeProfileSource.next(p);
});
}
}
SelectProfileComponent
包含一个包含个人资料的列表,该列表会在选择change
时触发SearchProfile
- 事件。
<select (change)="setActiveProfile($event.target.value)">
<option *ngFor="let profile of profiles" [value]="profile.Id" [innerHtml]="profile.name"></option>
</select>
export class ProfileSelectionComponent implements OnInit {
private profiles: ISearchProfile[] = null;
constructor(private profileService: ProfileService) {}
//get profiles logic
public setActiveProfile(profileId: number): void {
this.profileService.selectProfile(profileId);
}
}
SearchProfileComponent
与Subscription
有一个activeProfile
,应该显示activeProfile
的属性,以便用户可以编辑它们。
SearchProfileComponent
看起来像这样:
<form [formGroup]="profileForm" *ngIf="!isLoading">
<input type="text" name="name" formControlName="name" [(ngModel)]="searchProfile.name" />
</form>
export class SearchProfileComponent implements OnInit {
private isLoading: boolean = true;
private activeProfileSubscription: Subscription;
private searchProfile: ISearchProfile = null;
public profileForm: FormGroup;
constructor(private profilService: ProfileService
private formBuilder: FormBuilder) { }
ngOnInit() {
this.activeProfileSubscription = this.profileService.activeProfile$.subscribe((profile: ISearchProfile) => {
this.searchProfile = profile;
this.createForm();
this.isLoading = false;
});
}
private createForm() {
this.profileForm = this.formBuilder.group({
["name"]: [this.searchProfile.name, null]
});
}
}
答案 0 :(得分:5)
我以这种方式解决了这个问题:
之前:
formControlName="description"
之后:
[formControl]="form.controls['description']"
答案 1 :(得分:1)
我通过在组件构造函数中初始化一次窗体来解决了这个问题 即
import UIKit
class CustomPickerView: UIPickerView {
init() {
super.init(frame: .zero)
}
override func layoutSubviews() {
super.layoutSubviews()
subviews.forEach { $0.backgroundColor = .clear }
}
override init(frame: CGRect) {
fatalError("init(coder:) has not been implemented")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
OR
constructor() {
this.form = this.initForm();
}
并在没有构造函数的组件中的任何位置删除组件中表单的重新初始化 即
ngOnInit() {
this.form = this.initForm();
}
答案 2 :(得分:0)
创建FormGroup
有点不对劲。您不需要将控件名称括在括号和双引号中。在官方角度文档上阅读有关reactive forms的更多信息。
从此处更改您的FormGroup创建:
this.profileForm = this.formBuilder.group({
["name"]: [this.searchProfile.name, null]
});
到此:
this.profileForm = this.formBuilder.group({
name: [this.searchProfile.name]
});
你应该在你的HTML中做一些改变。提示:如果您使用的是被动表单,则在导入时不需要[(ngModel)]
,请将其删除。这是正确的HTML输入:
<form [formGroup]="profileForm" *ngIf="!isLoading">
<input type="text" name="name" formControlName="name" />
</form>
答案 3 :(得分:0)
我发现使用[formControl]="$form.something"
方法效果很好。笨拙,但这对您来说是Angular。