没有 FormControl 实例附加到具有名称的表单控件元素

问题描述 投票:0回答:4

我在 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]
        });
    }
}
angular angular2-forms
4个回答
90
投票

我是这样解决的:

之前:

formControlName="description"

之后:

[formControl]="form.controls['description']"

5
投票

我通过在组件构造函数中初始化表单一次解决了这个问题 即

constructor() {
        this.form = this.initForm();
}

ngOnInit() {
        this.form = this.initForm();
}

并删除组件中任何位置不带构造函数的表单的重新初始化 即

this.form = this.initForm();

5
投票

你的

FormGroup
的创建有点错误。您不需要将控件名称括在方括号和双引号中。在官方 Angular 文档中阅读有关 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>

-1
投票

我发现使用

[formControl]="$form.something"
方法效果很好。笨重,但这就是 Angular 适合你的地方。

© www.soinside.com 2019 - 2024. All rights reserved.