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

时间:2018-03-15 10:24:59

标签: angular angular2-forms

我在Angular 2中创建了一个表单,用户可以使用该表单编辑SearchProfile,他们可以从列表中进行选择。最初一切正常但是当我从SearchProfile列表中选择一个不同的项时,我收到以下异常: There is no FormControl instance attached to form control element with name: controlName。 整件事由3个元素组成:2个组件SelectProfileComponentSearchProfileComponent和服务ProfileServiceProfileService包含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);
    }
}

SearchProfileComponentSubscription有一个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]
        });
    }
}

4 个答案:

答案 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。