无法使用组件工厂在字符串“ userForm”上创建属性“ validator”

h

我正在尝试实现一个组件工厂来动态创建我的登录表单。最初,我遇到的问题是FormGroup无法在添加组件的表单中进行标识。最终,当我使用此处提供的解决方案使它通过时,我遇到了另一个错误:

TypeError:无法在字符串“ userForm”上创建属性“ validator”

当我点击ng serve并浏览我的登录页面时,该错误会在控制台中弹出,并伴随着一个非常奇怪的表单布局(当我将输入插入表单本身而不是尝试添加组件时,我的表单就可以正常工作了。 ),如下所示:

第一次加载

如您所见,组件(第一个输入字段)的样式甚至不像第二个输入字段(直接添加到表单),并且单击一次或两次后,表单(几乎)又变回其原始形状,并出现另一个错误在控制台中:

TypeError:this.form.get不是一个函数

后

我不确定为什么会这样,以及我用来解决FormGroup问题的解决方案是否可能导致了问题。

这是我的代码:

login.component.ts

import { Component, OnInit, ViewChild, ViewContainerRef, AfterContentInit, ComponentFactoryResolver } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { OauthService } from 'src/app/services/oauth/oauth.service';
import { LoggerService } from 'src/app/services/logger/logger.service';
import { ToastrService } from 'ngx-toastr';
import { TranslatePipe } from 'src/app/pipes/translate/translate.pipe';
import { TextFieldComponent } from 'src/app/components/core/text-field/text-field.component';

/**
* This component is rendered at the start of application, it provides the UI
* & functionality for the login page.
*/
@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})

/**
* This class is used to build a login form along with initialization of validators
* as well as authenticate the user, and reroute upon success
*/
export class LoginComponent implements OnInit, AfterContentInit{

  @ViewChild('input', { read: ViewContainerRef }) container;

  /**
  * This property initializes the formGroup element.
  */
  userForm: FormGroup;
  /**
  * The constructor initializes Router, FormBuilder, OauthService, LoggerService, ToastrService
  * & TranslatePipe in the component.
  */
  constructor(private router: Router,
    private fb: FormBuilder,
    private oauth: OauthService,
    private logger: LoggerService,
    private toastr: ToastrService,
    private translate: TranslatePipe,
    private resolver: ComponentFactoryResolver) { }
  /**
  * This is the hook called on the initialization of the component, it initializes
  * the form.
  */
  ngOnInit() {
    this.buildForm();
  }



  /**
   * This method initialized the the formGroup element. Its properties and the validators.
   *
   * @method buildForm
   * @return
   */
  buildForm() {
    this.userForm = this.fb.group({
      'username': ['', Validators.required],
      'password': ['', Validators.required],
    });
  }
  /**
   * This method returns the values of the form controls.
   *
   * @return
   */
  get form() { return this.userForm.controls; }
  /**
   * This method is triggered on success, it reroutes the user to main page.
   *
   * @return
   */
  onSuccess() {
    let result = this.translate.transform("pages[login_page][responses][success]");
    this.logger.info(result);
    this.toastr.success(result);
    this.router.navigate(['main']);
  }
  /**
   * This method is triggered when user clicks log-in, it calls the aunthenication method
   * from oauth service.
   *
   * @return
   */
  login() {
    this.oauth.authenticateUser(this.form.username.value, this.form.password.value, this.onSuccess.bind(this));
  }

  ngAfterContentInit() {
    let data = {
      type: "text",
      class: "form-control",
      placeholder: this.translate.transform("pages[login_page][login_form][placeholders][username]"),
      id: "username",
      autoComplete: "username",
      formControlName: "username",
      group: "userForm"
    }
    const inputFactory = this.resolver.resolveComponentFactory(TextFieldComponent);
    const usernameField = this.container.createComponent(inputFactory);
    usernameField.instance.group = data.group;
    usernameField.instance.type = data.type;
    usernameField.instance.class = data.class;
    usernameField.instance.placeholder = data.placeholder;
    usernameField.instance.id = data.id;
    usernameField.instance.autoComplete = data.autoComplete;
    usernameField.instance.formControlName = data.formControlName;
  }

}

login.component.html

<div class="app-body">
  <main class="main d-flex align-items-center">
    <div class="container center">
      <div class="row">
        <div class="col-md-8 mx-auto">
          <div class="card-group">
            <div class="card p-4">
              <div class="card-body">
                <form [formGroup]="userForm" (submit)="login()">
                  <h1>{{ 'pages[login_page][login_form][labels][login]' | translate }}</h1>
                  <p class="text-muted">{{ 'pages[login_page][login_form][labels][sign_in]' | translate }}</p>
                  <div class="input-group mb-3">
                    <div class="input-group-prepend">
                      <span class="input-group-text"><i class="icon-user"></i></span>
                    </div>
                    <div #input> </div>
                  <!--  <input type="text" class="form-control" placeholder="{{ 'pages[login_page][login_form][placeholders][username]' | translate }}"  id="username" autocomplete="username" formControlName="username"> -->
                  </div>
                  <div class="input-group mb-4">
                    <div class="input-group-prepend">
                      <span class="input-group-text"><i class="icon-lock"></i></span>
                    </div>
                    <input type="password" class="form-control" placeholder="{{ 'pages[login_page][login_form][placeholders][password]' | translate }}" id="password" autocomplete="current-password" formControlName="password" >
                  </div>
                  <div class="row">
                    <div class="col-6">
                      <button type="button" class="btn btn-primary px-4" (click)="login()">{{ 'pages[login_page][login_form][buttons][login]' | translate }}</button>
                    </div>
                    <div class="col-6 text-right">
                      <button type="button" class="btn btn-link px-0">{{ 'pages[login_page][login_form][urls][forgot_password]' | translate }}</button>
                    </div>
                  </div>
                </form>
              </div>
            </div>
            <div class="card text-white bg-primary py-5 d-md-down-none" style="width:44%">
              <div class="card-body text-center">
                <div>
                  <h2>{{ 'pages[login_page][sign_up_panel][labels][sign_up]' | translate }}</h2>
                  <p>{{ 'pages[login_page][sign_up_panel][labels][new_account]' | translate }}</p>
                  <button type="button" class="btn btn-primary active mt-3">{{ 'pages[login_page][sign_up_panel][buttons][register]' | translate }}</button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </main>
</div>

text-field.component.html

<div [formGroup]="group">
  <input type="{{ type }}" class="{{ class }}" placeholder="{{ placeholder }}" id="{{ id }}" autocomplete="{{ autoComplete }}" formControlName="{{ formControlName }}">  
</div>

text-field.component.ts

import { Component, OnInit, ViewEncapsulation, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';

@Component({
  selector: 'app-text-field',
  templateUrl: './text-field.component.html',
  styleUrls: ['./text-field.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class TextFieldComponent implements OnInit {

  @Input() group: FormGroup;
  @Input() type: string;
  @Input() placeholder: string;
  @Input() class: string;
  @Input() id: string;
  @Input() autoComplete: string;
  @Input() formControlName: string;


  constructor() {}

  ngOnInit() {}

}

概要

预期:表单应与动态组件一起正确使用

实际:提供错误和样式的表格也无法正常工作

阿米特·奇加丹尼(Amit Chigadani)

您正在"userForm"为组属性分配一个字符串,而您应该在其中分配实际形式this.userForm

let data = {
      type: "text",
      class: "form-control",
      placeholder: this.translate.transform("pages[login_page][login_form][placeholders][username]"),
      id: "username",
      autoComplete: "username",
      formControlName: "username",
      group: this.userForm              // see this line
    }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

TypeError:无法在setUpControl的字符串“ [email protected]”上创建属性“ validator”

收到错误“ TypeError:无法在字符串'control'上创建属性'validator'”

水豚字符串数组类型fill_in失败,无法使用工厂创建的数据

在GAE上使用Hibernate Validator 5?

Angular TypeError:无法在字符串''上创建属性

类型错误:无法在字符串 'a' 上创建属性 'style'

TypeError:无法在字符串“ /:id”上创建属性“ next”

无法在字符串 '' 上创建属性 'fillColor'

使用gmail的Nodemailer,无法在字符串“ SMTP”上创建属性“ mailer”

无法为使用字符串作为参数的角组件创建构造函数

“无法分配给“formControlAnimalSelect”上的属性“validator”:不是对象”Angular Typescript

错误TypeError:“无法在“ signUpForm”上分配给属性“ validator”:不是对象”

TS2511:无法创建抽象类“ Validator”的实例

jQuery Validator在选择下拉列表上无法正常工作

如何在kendoMultiSelect和kendoDropDownList上使用Bootstrap Validator?

TS:如何使用字符串创建类型工厂以生成密钥

无法在字符串'__zone_symbol__optimizedZoneEventTask'上创建属性'__creationTrace__'

无法在字符串“ Information Technology” angularjs上创建“ selected”属性

未被捕获的TypeError:无法在字符串'上创建属性'guid'

未捕获的TypeError:无法在字符串“ wtd_background_image”上创建属性“ style”

未被捕获的TypeError:无法在字符串“”上创建属性“ empFirstName”

使用ngFormModel(ES6)时angular2无法读取未定义的属性'validator'

如何从字符串创建组件

Hibernate Validator的@SafeHtml可以使用哪些替代方法来验证字符串?

无法使用\ n分割从char数组创建的字符串

无法使用字符串创建NSUUID

Spring Validator:无法自动接线。找不到“ Validator”类型的bean

无法使用Selenium在Element上输入字符串

使用Laravels Validator验证数组