angular - Hvordan endre HTML-elementets readonly- og required-attributt i Angular2 Typescript?


For noen av komponentene mine vil jeg gjerne kunne endre input-feltets readonly- og required-attributter frem og tilbake.

Jeg har klart å få en fungerende kode som endrer begge etter behov, men problemet er at det fungerer for readonly, men ser ut til ikke å fungere for required: selv om elementattributtet endres til required, tror Angular2 fortsatt at fieldCtrl er gyldig.

Her er min plunker, hvor jeg illustrerte dette problemet: https://plnkr.co/edit/Yq2RDzUJjLPgReIgSBAO?p=preview

//our root app component
import {Component} from 'angular2/core'

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div>
    <form #f="ngForm">
      <button type="button" (click)="toggleReadOnly()">Change readonly!</button>
      <button type="button" (click)="toggleRequired()">Change required!</button>
      <input id="field" [(ngModel)]="field" ngControl="fieldCtrl" #fieldCtrl="ngForm"/>
      {{fieldCtrl.valid}}
    </form>
    </div>
  `,
  directives: []
})
export class App {
  constructor() {
    this.name = 'Angular2'
  }

  toggleRequired(){
    this.isRequired = !this.isRequired;
    var fieldElement = <HTMLInputElement>document.getElementById('field');
    if (this.isRequired){
      fieldElement.required = true;
      this.field = "it's required now";
    }
    else{
      fieldElement.required = false;
      this.field = "can leave it blank";
    }
  }

  toggleReadOnly(){
    this.isReadOnly = !this.isReadOnly;
    var fieldElement = <HTMLInputElement>document.getElementById('field');
    if (this.isReadOnly){
      fieldElement.readOnly = true;
      this.field = "it's readonly now";
    }
    else{
      fieldElement.readOnly = false;
      this.field = "feel free to edit";
    }
  }

  private isReadOnly:boolean=false;

  private field:string = "feel free to edit";

  private isRequired:boolean=false;

}

OPPDATERING: Prøvde foreslått metode

[required]="isRequired" [readonly]="isReadOnly"

Og det fungerer som en drøm for readonly, og for required=true, men jeg kan ikke slå av required-attributtet lenger - det viser tomt felt som ugyldig selv om det ikke lenger er påkrevd.

Oppdatert plunker: https://plnkr.co/edit/6LvMqFzXHaLlV8fHbdOE

OPPDATERING2: Prøvde foreslått metode

[required]="isRequired ? true : null"

Det legger til/fjerner krav-attributtet fra elementet etter behov, men feltkontrollerens gyldig-egenskap viser false for et tomt felt som ikke er påkrevd.

Hva ville være korrekt måte å endre nødvendig attributt på i Angular2 Typescript?

Svar #1

For at bundne attributter skal fjernes, må de settes til null. Det var en diskusjon om å endre det til å fjerne ved false, men det ble avslått, i det minste for nå.

 [required]="isRequired ? '' : null"

eller

 [required]="isRequired ? 'required' : null"

Din Plunker gir en feil på grunn av manglende [] rundt ngControl.

Se også denne Plunker for et fungerende eksempel

Se også Deilans kommentarer nedenfor.

Svar #2

Det ser ut til at du allerede har et svar for å legge til/fjerne readonly-attributtet. For required-attributtet foreslår jeg å lage en tjeneste for å holde oversikt over aktivert/deaktivert-tilstanden til validatoren, og deretter bruke tjenesten når du binder til valideringskontrollene dine.

Statlig validator

Denne klassen er ansvarlig for å holde oversikt over validatoren og dens aktivert/deaktivert tilstand.

export class StateValidator {
    public enabled: boolean = true;
    validator: (control: Control) => { [key: string]: boolean };
    constructor(validator: (control: Control) => 
        { [key: string]: boolean }, enabled: boolean) {
        this.enabled = enabled;
        this.validator = validator;

    }

    enable() {
        this.enabled = true;
    }
    disable() {
        this.enabled = false;
    }
    toggle() {
        this.enabled = !this.enabled;
    }
    get() {
        return (control: Control) => {
            if (this.enabled)
                return this.validator(control);
            return null;
        }
    }
}

Den har metoder for å aktivere, deaktivere eller veksle validatoren; og også en get-metode som returnerer en ny validatorfunksjon, som når den påkalles vil kalle den underliggende validatorfunksjonen dersom validatoren er aktivert, eller returnere null når validatoren ikke er aktivert.

Valideringstjeneste

Denne klassen er en singleton-tjeneste som er ansvarlig for å registrere validatorer etter nøkkel, og støtter metoder for å aktivere, deaktivere eller bytte en validator basert på den nøkkelen.

export class ValidationService {
    validators: { [key: string]: StateValidator } = {};
    register(key: string, validator: Function): Function {
        var stateValidator = new StateValidator(<(control: Control) => { [key: string]: boolean }>validator, true);
        this.validators[key] = stateValidator;
        return stateValidator.get();
    }
    enable(key: string) {
        this.validators[key].enable();
    }
    disable(key: string) {
        this.validators[key].disable();
    }
    toggle(key: string) {
        this.validators[key].toggle();
    }
    list() {
        var l = [];
        for (var key in this.validators) {
            if (this.validators.hasOwnProperty(key)) {
                l.push({ key: key, value: this.validators[key].enabled });
            }
        }
        return l;
    }
}

Tjenesten har også en list-funksjon for å returnere en liste med nøkkel/verdi-par der nøkkelen representerer den registrerte validatornøkkelen, og verdien er en boolsk indikator som representerer validatorens aktive tilstand.

Komponent

For å bruke ValidationService, registrer tjenesten med rotinjeksjonen under oppstart:

bootstrap(AppComponent, [ValidationService]);

Eller registrer tjenesten med komponentnivåets injektor:

@Component({
  selector: 'app',
  providers: [ValidationService],
  ...
})

Deretter injiser tjenesten i komponentens konstruktør:

export class AppComponent {
    form: ControlGroup;
    constructor(public validationService:ValidationService) {
      ...
    }
}

Neste, bind til valideringskontrollene som du normalt ville gjort, bortsett fra at du bruker ValidationService for å registrere og returnere tilstandsvalidatoren:

new Control('', validationService.register('required', Validators.required));

En av de flotte tingene med denne løsningen er at du enkelt kan komponere og blande tilstandsvaliderere med andre innebygde eller tilpassede validerere:

this.form = new ControlGroup({
    name: new Control('hello',
        Validators.compose([
            validationService.register('required', Validators.required),
            validationService.register('minlength', Validators.minLength(4)),
            Validators.maxLength(10)]))

});

Bytte på validatoren

Bruk tjenesten for å bytte tilstanden til validatoren:

validationService.toggle('required');

Her er et eksempel på hvordan du binder til listen over tilstandsvaliderere i en tabell, og kobler vekslefunksjonen til et knappetrykkhendelse:

<table>
  <tr>
     <td>Validator</td>
     <td>Is Enabled?</td>
     <td></td>
  </tr>
  <tr *ngFor="#v of validationService.list()">
     <td>{{v.key}}</td>
     <td>{{v.value }}</td>
     <td><button (click)="validationService.toggle(v.key)">Toggle</button></td>
  </tr>
</table>

Demo Plnkr

Relaterte artikler