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 并通过共享服务与其他同级组件进行交互。

感谢大家的帮助。