Angular 角度材质窗体不工作-mat窗体字段必须包含MatFormFieldControl

Angular 角度材质窗体不工作-mat窗体字段必须包含MatFormFieldControl,angular,typescript,angular-material,Angular,Typescript,Angular Material,我正在尝试创建一个简单的应用程序来管理我们的流媒体设备的配置。然而,我不能让它工作,虽然一切都应该是好的-导入模块,标记指令。。。这是我的第一个angular应用程序,它是根据文档生成的(所有内容的最新版本) 在.ts文件中,我从服务器获取带有设置的json(为了简单起见,我只处理其中的一部分)。我使用FormBuilder构建FormGroup并用值填充它。当我记录它时,它看起来很好-FormGroups/FormControls在它们应该在的地方,值是ok的。然而,当我试图在模板中呈现它时,

我正在尝试创建一个简单的应用程序来管理我们的流媒体设备的配置。然而,我不能让它工作,虽然一切都应该是好的-导入模块,标记指令。。。这是我的第一个angular应用程序,它是根据文档生成的(所有内容的最新版本)

在.ts文件中,我从服务器获取带有设置的json(为了简单起见,我只处理其中的一部分)。我使用FormBuilder构建FormGroup并用值填充它。当我记录它时,它看起来很好-FormGroups/FormControls在它们应该在的地方,值是ok的。然而,当我试图在模板中呈现它时,它失败了,出现了上述错误。通过添加指令或导入模块解决了类似的问题,但正如我所说的,我应该拥有所需的一切。谢谢你的回复,我现在很沮丧

编辑:对不起,我忘了包括我从服务器获得的数据-我在构造函数中伪造它

模板

<p>streamer-configuration works!</p>

<div>
  <form *ngIf="config" [formGroup]="configForm" (ngSubmit)="onSubmit(configForm)">
    <b>Conference:</b>
    <mat-form-field appearance="standard">
      <mat-label>Enabled</mat-label>
      <input matInput formControlName="enabled" value="{{ config["enabled"] }}" required />
    </mat-form-field>
    <mat-form-field appearance="standard">
      <mat-label>Auto answer</mat-label>
      <input matInput formControlName="auto_answer" value="{{ config["auto_answer"] }}" required />
    </mat-form-field>
    <mat-form-field appearance="standard">
      <mat-label>Port</mat-label>
      <input matInput formControlName="port" value="{{ config["port"] }}" required />
    </mat-form-field>
    <div formGroupName="technology">
      <mat-form-field appearance="standard">
        <mat-label>Selected technology</mat-label>
        <input matInput formControlName="selected" value="{{ config["technology"]["selected"] }}" required />
      </mat-form-field>
    </div>
    <button mat-raised-button color="primary" type="submit">Submit</button>
  </form>
</div>
import { Component, OnInit, createPlatformFactory } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { FormBuilder } from '@angular/forms';
import { ConstantsService } from '../common/services/constants.service';

@Component({
  selector: 'app-streamer-configuration',
  templateUrl: './streamer-configuration.component.html',
  styleUrls: ['./streamer-configuration.component.scss']
})
export class StreamerConfigurationComponent implements OnInit {
  private apiURL: string;
  config: Object;
  configForm: Object;

  constructor(private http: HttpClient, private formBuilder: FormBuilder, private _constant: ConstantsService) {
    this.apiURL = `${this._constant.baseApiUrl}/xxx`;
    this.getData();
  }

  ngOnInit(): void {
  }

  private getData() {
    return this.http.get(this.apiURL).subscribe(config => {
      console.log(config);
      this.config = config["Conference"];
      this.createConfigForm();
    });
  }

  private createConfigForm(obj = this.config) {
    this.configForm = this.formBuilder.group({
      enabled: [obj["enabled"]],
      auto_answer: [obj["auto_answer"]],
      technology: this.formBuilder.group({
        selected: [obj["technology"]["selected"]]
      }),
      port: [obj["port"]]
    })
    console.log(this.configForm);
  }

  onSubmit(data) {
    console.log(data);
  }
}
应用程序模块.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { ConfigSectionsComponent } from './config-sections/config-sections.component';
import { LayoutModule } from '@angular/cdk/layout';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatButtonModule } from '@angular/material/button';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatIconModule } from '@angular/material/icon';
import { MatListModule } from '@angular/material/list';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input'; // <-----------
import { FormsModule, ReactiveFormsModule  } from '@angular/forms';

import { StreamerConfigurationComponent } from './streamer-configuration/streamer-configuration.component';
import { ManifestConfigurationComponent } from './manifest-configuration/manifest-configuration.component';
import { NetworkCamerasComponent } from './network-cameras/network-cameras.component';
import { CamerasIconsComponent } from './cameras-icons/cameras-icons.component';

import { ConstantsService } from './common/services/constants.service';

import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent,
    ConfigSectionsComponent,
    StreamerConfigurationComponent,
    ManifestConfigurationComponent,
    NetworkCamerasComponent,
    CamerasIconsComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    HttpClientModule,
    LayoutModule,
    MatToolbarModule,
    FormsModule,
    MatButtonModule,
    MatSidenavModule,
    MatIconModule,
    MatListModule,
    MatFormFieldModule,
    MatInputModule, // <----------
    ReactiveFormsModule,
  ],
  providers: [ConstantsService],
  bootstrap: [AppComponent]
})
export class AppModule { }
从'@angular/platform browser'导入{BrowserModule};
从“@angular/core”导入{NgModule};
从“./app routing.module”导入{AppRoutingModule};
从“./app.component”导入{AppComponent};
从“@angular/platform browser/animations”导入{BrowserAnimationsModule};
从“./config sections/config sections.component”导入{ConfigSectionsComponent};
从'@angular/cdk/layout'导入{LayoutModule};
从“@angular/material/toolbar”导入{MatToolbarModule};
从“@angular/material/button”导入{MatButtonModule};
从'@angular/material/sidenav'导入{MatSidenavModule};
从“@angular/material/icon”导入{MatIconModule};
从'@angular/material/list'导入{MatListModule};
从“@angular/material/form field”导入{MatFormFieldModule};
从“@angular/material/input”;/”导入{MatInputModule} 里尼克,三个音符

1.-如果使用插值,请在双引号之间使用单引号

//WRONG
value="{{ config["technology"]["selected"] }}"

//OK
value="{{ config['technology']['selected'] }}"
//OR
value="{{config.technology.selected}}"
//OR
[value]="config.technology.selected"
2.-如果您使用被动形式,而不是使用“值”,只需给formControl赋值即可

//WRONG
<input matInput formControlName="port" value="{{ config['port'] }}" required />

//OK
<input matInput formControlName="port"  required />
//错了
//嗯
3.-在提交功能中,您通过表单,因此,您的提交必须如下

  onSubmit(formGroup:FormGroup) {
    if (formGroup.valid)
      console.log(formGroup.value); //<--see how get the "data"
    }
  }
onSubmit(formGroup:formGroup){
if(formGroup.valid)

console.log(formGroup.value);//请发布一个最小的可复制示例。我导入了您提供的代码(减去对缺少部分的引用)错误不会重现。请看下面的stackblitz:@TomMettam抱歉我忘了,用愚蠢的引号更新了问题,我不知道我怎么会错过……还有第二点——因为“连接”对于保存formControl值的form对象,是吗?是的,如果您使用ReactiveForm,那么它不必要地给出“值”(如果使用[(ngModel)],也会发生这种情况),否则您会说Angular make the things两次