【问题标题】:There is no FormControl instance attached to form control element with name没有 FormControl 实例附加到具有名称的表单控件元素
【发布时间】:2018-08-24 02:50:21
【问题描述】:

我在 Angular 2 中创建了一个表单,用户可以使用该表单编辑 SearchProfile,他们可以从列表中进行选择。最初一切正常,但是当我从SearchProfiles 列表中选择不同的项目时,我收到以下异常: 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 包含一个带有配置文件的列表,该配置文件在选择 SearchProfile 时触发 change 事件。

<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);
    }
}

SearchProfileComponentactiveProfile 之间有一个Subscription,并且应该显示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


    【解决方案1】:

    我是这样解决的:

    之前:

    formControlName="description"
    

    之后:

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

    【讨论】:

    • 感谢@Kuzenko Lubko,这是有效的!我想知道,这看起来像一个错误,你能说出为什么 formControlName 在这种情况下不起作用吗?
    • @benshabatnoam 可能是因为表单将在异步请求后创建。如果您使用的是 formControlName,您应该在视图渲染之前创建表单。
    • 你说得对,我在渲染视图后动态构建formGroup,但我的表单上有一个*ngIf。我想这就是问题所在。谢谢!
    • 我只是在我的数字控制中的向上/向下箭头崩溃,这治愈了它。所以这是视图渲染发生的事情。
    【解决方案2】:

    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>
    

    【讨论】:

      【解决方案3】:

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

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

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

      并在组件中任意位置移除窗体的重新初始化,无需构造函数 即

      this.form = this.initForm();
      

      【讨论】:

      • 谢谢,我的问题是由于编辑表单中的其他条件,我正在检查数据以填写表单,或者如果数据不存在则重新初始化表单。 @Saad
      【解决方案4】:

      我发现使用[formControl]="$form.something" 方法效果很好。笨重,但这对你来说是 Angular。

      【讨论】:

        猜你喜欢
        • 2022-01-22
        • 2012-05-23
        • 1970-01-01
        • 1970-01-01
        • 2018-12-05
        • 1970-01-01
        • 2013-04-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多