- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试实现一个组件工厂来动态创建我的登录表单。最初,我遇到了 FormGroup
未被我添加组件的表单识别的问题。最后,当我使用提供的解决方案通过时 here我遇到了另一个错误:
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() {}
}
总结
预期:表单应该与动态组件一起正常工作
实际:表单给出错误和样式也不起作用
最佳答案
您正在将字符串 "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
}
关于html - 无法在字符串 'validator' 上创建属性 'userForm' - 使用组件工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54820622/
我应该执行以下操作: 可能通过服务/工厂,使用 $q(异步)查询 API 以获取大型名称数据集 有另一个服务(也是异步的),它应该只返回上述工厂的元素,如果它们与某个字符串(搜索字段)匹配。目的是缩小
我有一个通用的基类。我有一个实现基类的具体类。 我将如何创建工厂类/方法来交付不同类型的具体类? 举个例子: public class ReceiverBase where T : IInte
我正在查看以下链接中的 Ninject Factory 扩展: http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-intro
工厂、提供商和服务这三个术语之间有什么区别? 刚刚了解 NHibernate 及其存储库模式(POCO 类等)。 最佳答案 工厂:通过将一堆位组合在一起或基于某种上下文选择类型来组装类 Provide
使用CGLIB我可以做到 final var enhancer = new Enhancer(); enhancer.setUseCache(false); enhancer.setSuperclas
我试图在 Kotlin 中使用伴随对象工厂方法(相当于 Java 中的静态工厂方法)创建一个嵌套内部类。这是我的代码的简化版本。 class OuterClass { var myData:L
我正在为我的大学做一个项目,但遇到了问题。 基本上,该项目由一个客户端-服务器应用程序组成,我想创建一个用于通信的 Packet 类。数据包由 header 和主体组成。现在问题来了。我可以有一些不同
这个问题在这里已经有了答案: Why doesn't polymorphism work without pointers/references? (6 个答案) What is object sl
我正在制作一个套接字工厂。我希望每个外部应用程序都使用 Socket 类的接口(interface),它是几个类(ServerSocketTCP、ClientSocketTCP、ServerSocke
我是 angularjs 的新手,我正在尝试创建一个小型电影数据库。这是我第一次使用工厂,我想确保这是正确的方法,以及如何在另一个功能中使用这个工厂,如下所示? 我希望这个工厂只运行一次,这样我就可以
这个问题在这里已经有了答案: Java inner class and static nested class (28 个答案) 关闭 5 年前。 public class DataFactory
我看过很多关于 C++ 工厂的帖子,但到目前为止我还没有看到解决我的问题的解决方案。 (虽然我可能遗漏了一些东西。) 示例控制台应用程序: #include #include #include
这是一个简单的 C++ 项目,有 2 种设计模式:单例和工厂,sigleton 也是一个模板化类,一个接口(interface) (IHash) 和一个类 (Hash1)。一个简单的工厂类 (Hash
这个问题类似于Factory and generics ,并且可能有相同的答案,但它是不同的。我有一个通用基类,它将由完全独立的 JAR 中的类进行扩展。所述 JAR 应该能够在不更改任何其他代码的情
问题是我需要为传递的类创建一个新实例 有没有办法重写这个函数,让它可以接受任意数量的参数? function createInstance(ofClass, arg1, arg2, arg3, ...
我想用简单的 C++ 语法创建一个简单的工厂方法: void *createObject(const char *str,...) { if(!strcmp("X",str)) retu
经过大约 10 个月的程序化 PHP 学习后,我现在正尝试着手研究基本的 OOP 原则和设计模式。这是一个爱好,我没有那么多时间去追求它,所以请原谅这个问题的水平很低。 我的网站(目前 100% 程序
我有一个简单的问题。 我如何编写一个工厂来定义使用 make() 或 create() 的关系,具体取决于原始调用 make() 还是 create()? 这是我的用例: 我有一个简单的工厂 /**
我正在尝试在延迟加载模块中提供 APP_BASE_HREF 注入(inject) token ,然而,工厂方法根本没有被调用。 在这里https://github.com/MaurizioCascia
我有以下 ast: import { factory as f } from 'typescript' const typeDeclaration = f.createTypeAliasDeclara
我是一名优秀的程序员,十分优秀!