Angular2 表单控件
Angular2 FormControl
我正在使用模型驱动表单构建表单并使用 formcontrol 构建我的表单元素。我有一个服务,我在其中放置了一些函数,然后将表单组发送到该函数以访问表单控件。我想知道如何更改 formcontrols 属性来执行隐藏元素之类的操作。我在互联网上找不到执行此操作的方法。
感谢大家
编辑:
示例代码如下:
我的应用以 app.component.html
开头
<h1>
Orçamento
</h1>
<app-form [campos]="cpos"></app-form>
这是我的 app.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
cpos: any[] = [];
constructor() { }
ngOnInit() {
}
}
我有一个 class 叫做 campo-base.ts 它是我所有领域的基础:
export class CampoBase<T> {
nome: string;
valor: T;
label: string;
obrigatorio: boolean;
ordem: string;
tamanho: number;
tipoCampo: string;
combo: {chave: string, valor: string}[] = [];
tipo: string;
disabled: boolean;
tamcol: string;
espcol: string;
classe: string;
rowcol: number;
f3: string;
change: string;
visivel:boolean;
constructor (opcoes: {
valor?: T,
nome?: string,
label?: string,
obrigatorio?: boolean,
ordem?: string,
tamanho?: number,
tipoCampo?: string,
combo?: {chave: string, valor: string}[],
tipo?: string,
disabled?: boolean,
tamcol?: string,
espcol?: string,
classe?: string,
rowcol?: number,
f3?: string,
change?: string,
visivel?: boolean
} = {}) {
this.valor = opcoes.valor;
this.nome = opcoes.nome || '';
this.label = opcoes.label || '';
this.obrigatorio = !!opcoes.obrigatorio;
this.ordem = opcoes.ordem || '';
this.tamanho = opcoes.tamanho === undefined ? 1 : opcoes.tamanho;
this.tipoCampo = opcoes.tipoCampo || '';
this.combo = opcoes.combo || [];
this.tipo = opcoes.tipo || '';
this.disabled = !!opcoes.disabled;
this.tamcol = opcoes.tamcol || '';
this.espcol = opcoes.espcol || '';
this.classe = opcoes.classe || '';
this.rowcol = opcoes.rowcol === undefined ? 0 : opcoes.rowcol;
this.f3 = opcoes.f3 || '';
this.change = opcoes.change || '';
this.visivel = (!!opcoes.visivel ? true : opcoes.visivel);
}
}
我在 form.component.ts 中使用它,它从包含字段列表及其属性的服务接收数据。
import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { CampoBase } from './campo-base';
import { FormService } from "./form.service";
import { FormDadosService } from './form-dados.service';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css'],
providers:[FormService,FormDadosService]
})
export class FormComponent implements OnInit {
@Input() campos: CampoBase<any>[] = [];
formulario: FormGroup = new FormGroup({});
payLoad = '';
coluna: number = 0;
constructor(private formService: FormService, private servico: FormDadosService) { }
ngOnInit() {
this.servico.getCampos().subscribe((data) => {
let classe: string = '';
let combobox: {chave: string, valor:string}[] = [];
data.forEach(campo => {
classe = '';
//Ajusta os tamanhos dos campos no form
if (campo.ZI2_TIPO != '4') {
classe += 'form-group ';
if (campo.ZI2_ESPCOL !== '00') {
classe += 'col-md-' + parseInt(campo.ZI2_TAMCOL).toString() + ' col-md-pull-' + parseInt(campo.ZI2_ESPCOL).toString() + ' col-md-offset-' + parseInt(campo.ZI2_ESPCOL).toString();
classe += ' col-lg-' + parseInt(campo.ZI2_TAMCOL).toString() + ' col-lg-pull-' + parseInt(campo.ZI2_ESPCOL).toString() + ' col-lg-offset-' + parseInt(campo.ZI2_ESPCOL).toString();
} else {
classe += 'col-md-' + parseInt(campo.ZI2_TAMCOL).toString() + ' col-lg-' + parseInt(campo.ZI2_TAMCOL).toString();
}
}
//Calcula o tamanho dos campos na linha para adicionar um novo row
if (this.coluna >= 12) {
this.coluna = 0;
}
this.coluna += parseInt(campo.ZI2_TAMCOL) + parseInt(campo.ZI2_ESPCOL);
//Trata os campos combobox
combobox.length = 0;
if (campo.ZI2_CBOX !== null) {
for (let x in campo.ZI2_CBOX) {
if (campo.ZI2_CBOX.hasOwnProperty(x)) {
combobox.push({chave: x, valor: campo.ZI2_CBOX[x]});
}
}
}
//Instancia o campo e adiciona na lista de campos
this.campos.push(new CampoBase({
valor: '',
nome: campo.ZI2_CAMPO,
label: campo.ZI2_DESC,
tipoCampo: campo.ZI2_TIPO,
tamanho: campo.ZI2_TAM,
ordem: campo.ZI2_SEQ,
obrigatorio: campo.ZI2_OBRIGA === '1',
disabled: campo.ZI2_VISUAL !== "A",
classe: classe,
tamcol: campo.ZI2_TAMCOL,
espcol: campo.ZI2_ESPCOL,
rowcol: this.coluna,
f3: campo.ZI2_F3,
combo: combobox.slice(),
change: campo.ZI2_CHANGE,
visivel: true
}));
});
this.formulario = this.formService.toFormGroup(this.campos);
});
}
onSubmit() {
this.payLoad = JSON.stringify(this.formulario.value);
}
}
我使用 form-campo.component.ts:
构建我的表单
import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { CampoBase } from './campo-base';
import { OrcamentoService } from '../orcamento.service';
@Component({
selector: 'formcampos',
templateUrl: './form-campo.component.html',
styleUrls: ['./form-campo.component.css']
})
export class FormCampoComponent implements OnInit {
@Input() campo: CampoBase<any>;
@Input() form: FormGroup;
isValid() {
return this.form.controls[this.campo.nome].pristine || this.form.controls[this.campo.nome].valid;
}
constructor(private orcamentoService: OrcamentoService){}
ngOnInit() {
if (this.campo.change)
this.form.controls[this.campo.nome].valueChanges.subscribe(valor => {
let aChanges = this.campo.change.split(";");
let expression = "";
for (let i = 0; i < aChanges.length; i++) {
if (aChanges[i].length > 0) {
expression = "_this.orcamentoService." + aChanges[i].replace(/\(\)/g,"") + '(_this.form, valor)';
eval(expression);
}
}
});
}
}
使用此模板:
<div [formGroup]="form" [class]="campo.classe" *ngIf="campo.visivel">
<label [attr.for]="campo.nome" [hidden]="campo.tipoCampo === '4'">{{campo.label}}</label>
<div [class.input-group]="campo.f3">
<select *ngIf="(campo.tipoCampo == '1' || campo.tipoCampo == '3') && campo.combo.length > 0" [formControlName]="campo.nome" class="form-control" [id]="campo.nome">
<option *ngFor="let opt of campo.combo" [value]="opt.chave">{{opt.valor}}</option>
</select>
<input *ngIf="(campo.tipoCampo == '1' || campo.tipoCampo == '3') && campo.combo.length == 0" [formControlName]="campo.nome" class="form-control"
[id]="campo.nome" [type]="'text'" [maxlength]="campo.tamanho" [placeholder]="campo.label">
<input *ngIf="campo.tipoCampo == '2'" [formControlName]="campo.nome" class="form-control"
[id]="campo.nome" [type]="'email'" [maxlength]="campo.tamanho" [placeholder]="campo.label">
<input *ngIf="campo.tipoCampo == '4'" [formControlName]="campo.nome"
[id]="campo.nome" [type]="'hidden'">
<textarea *ngIf="campo.tipoCampo == '5'" [formControlName]="campo.nome" class="form-control"
[id]="campo.nome" [placeholder]="campo.label"></textarea>
<span class="input-group-btn" *ngIf="campo.f3">
<button class="btn btn-primary" type="button" id="f3{{campo.nome}}"><span class="glyphicon glyphicon-search"></span></button>
</span>
</div>
</div>
最后在 orcamento.service 中,我尝试操纵某些字段的可见性,如下所示:
import { Injectable } from '@angular/core';
@Injectable()
export class OrcamentoService {
constructor() { }
gatTipoOrc(form, valor) {
if (valor == "N") {
form.controls['ZPO_UM'].enable();
} else {
form.controls['ZPO_UM'].disable();
form.controls['ZPO_UM'].reset();
}
}
gatUM(form, valor) {
form.controls['ZPO_QTDPCX'].visivel = false;
}
habEntrega(form, valor) {
}
}
如果我对你的理解正确,你想做一些事情,比如隐藏一个元素 - <div hidden></div>
或者在 angular1 <div ng-hide="isHidden"></div>
在 angular2 中你应该绑定到类似于传统方式的元素属性:
<div [hidden]="true"></div>
。
当然可以使用变量,<div [hidden]="isHidden"></div>
另请注意,不推荐使用 hidden
:
编辑:
如 J. Adam Connor 所述,您也可以使用 *ngIf
而不是 [hidden]
。这将导致您的元素从 DOM 中完全删除,这通常是一种非常好的方法,但在与表单一起使用时应谨慎,因为某些验证和绑定要求您的表单与您的模型相匹配。如果 DOM.
中的实际表格中缺少它,那可能会很混乱
好吧,我使用 *ngIf 并通过共享服务与其他同级组件进行交互。
感谢大家的帮助。
我正在使用模型驱动表单构建表单并使用 formcontrol 构建我的表单元素。我有一个服务,我在其中放置了一些函数,然后将表单组发送到该函数以访问表单控件。我想知道如何更改 formcontrols 属性来执行隐藏元素之类的操作。我在互联网上找不到执行此操作的方法。
感谢大家
编辑:
示例代码如下:
我的应用以 app.component.html
开头<h1>
Orçamento
</h1>
<app-form [campos]="cpos"></app-form>
这是我的 app.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
cpos: any[] = [];
constructor() { }
ngOnInit() {
}
}
我有一个 class 叫做 campo-base.ts 它是我所有领域的基础:
export class CampoBase<T> {
nome: string;
valor: T;
label: string;
obrigatorio: boolean;
ordem: string;
tamanho: number;
tipoCampo: string;
combo: {chave: string, valor: string}[] = [];
tipo: string;
disabled: boolean;
tamcol: string;
espcol: string;
classe: string;
rowcol: number;
f3: string;
change: string;
visivel:boolean;
constructor (opcoes: {
valor?: T,
nome?: string,
label?: string,
obrigatorio?: boolean,
ordem?: string,
tamanho?: number,
tipoCampo?: string,
combo?: {chave: string, valor: string}[],
tipo?: string,
disabled?: boolean,
tamcol?: string,
espcol?: string,
classe?: string,
rowcol?: number,
f3?: string,
change?: string,
visivel?: boolean
} = {}) {
this.valor = opcoes.valor;
this.nome = opcoes.nome || '';
this.label = opcoes.label || '';
this.obrigatorio = !!opcoes.obrigatorio;
this.ordem = opcoes.ordem || '';
this.tamanho = opcoes.tamanho === undefined ? 1 : opcoes.tamanho;
this.tipoCampo = opcoes.tipoCampo || '';
this.combo = opcoes.combo || [];
this.tipo = opcoes.tipo || '';
this.disabled = !!opcoes.disabled;
this.tamcol = opcoes.tamcol || '';
this.espcol = opcoes.espcol || '';
this.classe = opcoes.classe || '';
this.rowcol = opcoes.rowcol === undefined ? 0 : opcoes.rowcol;
this.f3 = opcoes.f3 || '';
this.change = opcoes.change || '';
this.visivel = (!!opcoes.visivel ? true : opcoes.visivel);
}
}
我在 form.component.ts 中使用它,它从包含字段列表及其属性的服务接收数据。
import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { CampoBase } from './campo-base';
import { FormService } from "./form.service";
import { FormDadosService } from './form-dados.service';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css'],
providers:[FormService,FormDadosService]
})
export class FormComponent implements OnInit {
@Input() campos: CampoBase<any>[] = [];
formulario: FormGroup = new FormGroup({});
payLoad = '';
coluna: number = 0;
constructor(private formService: FormService, private servico: FormDadosService) { }
ngOnInit() {
this.servico.getCampos().subscribe((data) => {
let classe: string = '';
let combobox: {chave: string, valor:string}[] = [];
data.forEach(campo => {
classe = '';
//Ajusta os tamanhos dos campos no form
if (campo.ZI2_TIPO != '4') {
classe += 'form-group ';
if (campo.ZI2_ESPCOL !== '00') {
classe += 'col-md-' + parseInt(campo.ZI2_TAMCOL).toString() + ' col-md-pull-' + parseInt(campo.ZI2_ESPCOL).toString() + ' col-md-offset-' + parseInt(campo.ZI2_ESPCOL).toString();
classe += ' col-lg-' + parseInt(campo.ZI2_TAMCOL).toString() + ' col-lg-pull-' + parseInt(campo.ZI2_ESPCOL).toString() + ' col-lg-offset-' + parseInt(campo.ZI2_ESPCOL).toString();
} else {
classe += 'col-md-' + parseInt(campo.ZI2_TAMCOL).toString() + ' col-lg-' + parseInt(campo.ZI2_TAMCOL).toString();
}
}
//Calcula o tamanho dos campos na linha para adicionar um novo row
if (this.coluna >= 12) {
this.coluna = 0;
}
this.coluna += parseInt(campo.ZI2_TAMCOL) + parseInt(campo.ZI2_ESPCOL);
//Trata os campos combobox
combobox.length = 0;
if (campo.ZI2_CBOX !== null) {
for (let x in campo.ZI2_CBOX) {
if (campo.ZI2_CBOX.hasOwnProperty(x)) {
combobox.push({chave: x, valor: campo.ZI2_CBOX[x]});
}
}
}
//Instancia o campo e adiciona na lista de campos
this.campos.push(new CampoBase({
valor: '',
nome: campo.ZI2_CAMPO,
label: campo.ZI2_DESC,
tipoCampo: campo.ZI2_TIPO,
tamanho: campo.ZI2_TAM,
ordem: campo.ZI2_SEQ,
obrigatorio: campo.ZI2_OBRIGA === '1',
disabled: campo.ZI2_VISUAL !== "A",
classe: classe,
tamcol: campo.ZI2_TAMCOL,
espcol: campo.ZI2_ESPCOL,
rowcol: this.coluna,
f3: campo.ZI2_F3,
combo: combobox.slice(),
change: campo.ZI2_CHANGE,
visivel: true
}));
});
this.formulario = this.formService.toFormGroup(this.campos);
});
}
onSubmit() {
this.payLoad = JSON.stringify(this.formulario.value);
}
}
我使用 form-campo.component.ts:
构建我的表单import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { CampoBase } from './campo-base';
import { OrcamentoService } from '../orcamento.service';
@Component({
selector: 'formcampos',
templateUrl: './form-campo.component.html',
styleUrls: ['./form-campo.component.css']
})
export class FormCampoComponent implements OnInit {
@Input() campo: CampoBase<any>;
@Input() form: FormGroup;
isValid() {
return this.form.controls[this.campo.nome].pristine || this.form.controls[this.campo.nome].valid;
}
constructor(private orcamentoService: OrcamentoService){}
ngOnInit() {
if (this.campo.change)
this.form.controls[this.campo.nome].valueChanges.subscribe(valor => {
let aChanges = this.campo.change.split(";");
let expression = "";
for (let i = 0; i < aChanges.length; i++) {
if (aChanges[i].length > 0) {
expression = "_this.orcamentoService." + aChanges[i].replace(/\(\)/g,"") + '(_this.form, valor)';
eval(expression);
}
}
});
}
}
使用此模板:
<div [formGroup]="form" [class]="campo.classe" *ngIf="campo.visivel">
<label [attr.for]="campo.nome" [hidden]="campo.tipoCampo === '4'">{{campo.label}}</label>
<div [class.input-group]="campo.f3">
<select *ngIf="(campo.tipoCampo == '1' || campo.tipoCampo == '3') && campo.combo.length > 0" [formControlName]="campo.nome" class="form-control" [id]="campo.nome">
<option *ngFor="let opt of campo.combo" [value]="opt.chave">{{opt.valor}}</option>
</select>
<input *ngIf="(campo.tipoCampo == '1' || campo.tipoCampo == '3') && campo.combo.length == 0" [formControlName]="campo.nome" class="form-control"
[id]="campo.nome" [type]="'text'" [maxlength]="campo.tamanho" [placeholder]="campo.label">
<input *ngIf="campo.tipoCampo == '2'" [formControlName]="campo.nome" class="form-control"
[id]="campo.nome" [type]="'email'" [maxlength]="campo.tamanho" [placeholder]="campo.label">
<input *ngIf="campo.tipoCampo == '4'" [formControlName]="campo.nome"
[id]="campo.nome" [type]="'hidden'">
<textarea *ngIf="campo.tipoCampo == '5'" [formControlName]="campo.nome" class="form-control"
[id]="campo.nome" [placeholder]="campo.label"></textarea>
<span class="input-group-btn" *ngIf="campo.f3">
<button class="btn btn-primary" type="button" id="f3{{campo.nome}}"><span class="glyphicon glyphicon-search"></span></button>
</span>
</div>
</div>
最后在 orcamento.service 中,我尝试操纵某些字段的可见性,如下所示:
import { Injectable } from '@angular/core';
@Injectable()
export class OrcamentoService {
constructor() { }
gatTipoOrc(form, valor) {
if (valor == "N") {
form.controls['ZPO_UM'].enable();
} else {
form.controls['ZPO_UM'].disable();
form.controls['ZPO_UM'].reset();
}
}
gatUM(form, valor) {
form.controls['ZPO_QTDPCX'].visivel = false;
}
habEntrega(form, valor) {
}
}
如果我对你的理解正确,你想做一些事情,比如隐藏一个元素 - <div hidden></div>
或者在 angular1 <div ng-hide="isHidden"></div>
在 angular2 中你应该绑定到类似于传统方式的元素属性:
<div [hidden]="true"></div>
。
当然可以使用变量,<div [hidden]="isHidden"></div>
另请注意,不推荐使用 hidden
:
编辑:
如 J. Adam Connor 所述,您也可以使用 *ngIf
而不是 [hidden]
。这将导致您的元素从 DOM 中完全删除,这通常是一种非常好的方法,但在与表单一起使用时应谨慎,因为某些验证和绑定要求您的表单与您的模型相匹配。如果 DOM.
好吧,我使用 *ngIf 并通过共享服务与其他同级组件进行交互。
感谢大家的帮助。