Angular 7 - Disabled Property, je nach OnClick Event verschiedene Werte

  • Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Tabula_Rasa

Mitglied
12 Mai 2017
176
2
18
Hallo alle miteinander,

ich versuche Buttons je nach Klick zu "enablen" bzw. "disablen".

In der HTML-Datei

Code:
<p *ngFor="let item of items" (click)="buttonStatus(item)"> {{ statusMap[item.status] }} </p>
<button [disabled]="!isValid">Button1</button>
<button [disabled]="!isValid">Button2</button>
<button [disabled]="!isValid">Button3</button>
In der TypeScript-Datei

Code:
  statusMap = {
    1:false,
    2: true ,
    3:false
  };
 
  items = [{status: 1}, {status: 2}, {status:3}];


  isValid: false;
  buttonStatus(item){
    this.isValid = this.statusMap[item.status];
  }
Dieser Code stellt nur eine Simulation dar. Ich möchte nur folgende Logik verstehen:
Der folgende Code mapped nur die integer mit booleans. Die Variable isValid kann nur den Wert false oder true annehmen. Dementsprechend werden alle Buttons disabled bzw. enabled.

Ich möchte aber, dass bei einem Klick nicht unbedingt alle denselben Zustand annehmen, sondern verschiedene annehmen können bspw. soll beim Klick auf den ersten item.status mit dem Wert 1 nur der erste und der zweite disabled werden, aber nicht der dritte Button.

Mit isValid kriege ich das nicht hin, da die Variable nur einen Wert annehmen kann. Mir fällt leider die Logik dafür nicht ein, bestimmte Buttons zu disablen bzw. zu enablen bei einem Klick.

Ich brauche eure Hilfe :)!
 
Zuletzt bearbeitet:

Tronjer

Moderator
Team
Moderator
8 Oktober 2010
5.103
435
83
Berlin
Erstens hast du einen Fehler in deinem Code. Du initialisierst isValid nicht mit false, sondern weist das als Typ zu.

Zweitens ist das Mapping von Array und Objekt keine gute Idee. Das Integer ließe sich auch aus dem Template übernehmen.
HTML:
<p *ngFor="let item of items; let i = index" (click)="buttonStatus(i)"> {{ item.status }} </p>
Drittens belegst du alle Buttons mit derselben Variable. Die können nur gleichzeitig true oder false sein. Um das zu ändern, solltest du dem disabled eine Funktion übergeben, die unterschiedliche Zustände annehmen kann.
 
Reactions: Tabula_Rasa

Tabula_Rasa

Mitglied
12 Mai 2017
176
2
18
Erstens hast du einen Fehler in deinem Code. Du initialisierst isValid nicht mit false, sondern weist das als Typ zu.

Zweitens ist das Mapping von Array und Objekt keine gute Idee. Das Integer ließe sich auch aus dem Template übernehmen.
HTML:
<p *ngFor="let item of items; let i = index" (click)="buttonStatus(i)"> {{ item.status }} </p>
Drittens belegst du alle Buttons mit derselben Variable. Die können nur gleichzeitig true oder false sein. Um das zu ändern, solltest du dem disabled eine Funktion übergeben, die unterschiedliche Zustände annehmen kann.
Bei dem ersten Punkt erkenne ich den Fehler sofort ein "=" müsste dahin - danke dass du mich darauf aufmerksam gemacht. Beim ständigen Probieren tauchen schnell mal Syntax-Fehler auf.

Punkt 2: Theoretisch ginge es in diesem Beispiel auch mit deinem Code, aber es ist nur ein Beispiel. Möchte mich mich mit den Funktionalitäten vertraut machen, aber danke, dass du mich drauf aufmerksam machst, dass Mapping von Objekten und Arrays nicht die beste Alternative ist!

Punkt 3: Das Problem habe ich auch in der Frage geschildert. Dass eine Funktion übergeben werden muss ist mir klar. Ich habe mir folgendes überlegt:

Wie wäre es, wenn die Funktion den Status als Argument überliefert bekommt und dann per If-Abfrage oder switch funktion die disabled Eigenschaft auf true/false gesetzt wird? Dafür kriegt jeder Button eine id.
Der JavaScript Code, um den Wert der disabled Property zu ändern wäre:

Code:
document.getElementById("myBtn").disabled = true;
Leider finde ich nichts vergleichbares in TypeScript/Angular.

Ich versuchte einst per innerHTML den Text zwischen einem Paragraphen zu ändern, aber ich weiß einfach nicht, wie ich dieses document.getElementbyId in TypeScript nutzen kann.
Ich testete Code Samples von Foren wie stsckoverflow suchte generell im Internet jedoch vergebens. Damit könnte ich leicht die property ändern.

Weißt du vielleicht, wie man das in Typescript macht?
Beispielsweise hast du ein Button mit der id=btn. Wie kann ich diesen in der Ts Datei korrekt ansprechen?

Ich danke dir fürs viele Lesen und für das Aufmerksammachen vom schlechten Code!
 
Zuletzt bearbeitet:

Tronjer

Moderator
Team
Moderator
8 Oktober 2010
5.103
435
83
Berlin
Weißt du vielleicht, wie man das in Typescript macht?
Beispielsweise hast du ein Button mit der id=btn. Wie kann ich diesen in der Ts Datei korrekt ansprechen?
Gar nicht. Die eine Sache, die du unter keinen Umständen tun solltest, ist die direkte Manipulation von DOM-Elementen, wie bsw. per document.getElementById. Für das Template ist ausschließlich Angular zuständig und stellt dir dafür Direktiven wie *ngIf, *ngFor, etc. zur Verfügung. Vergiss am besten auch alles, was du jemals in jQuery gelernt hast.

Die Sache mit den drei disabled Buttons ist auch unüblich. Weil man normaler Weise nur einen hat, der bsw. die Validität eines Formulars prüft. Aber du könntest es bei deinem Beispiel doch so machen:
JavaScript:
<button class="btn btn-primary" [disabled]="validateButton(item, i)">Button1</button>

public validateButton(item, i): boolean {
    if ('foo' === 'bar') {
      // your code
      return true;
    }
    return false;
  }
 
Reactions: Tabula_Rasa

Tabula_Rasa

Mitglied
12 Mai 2017
176
2
18
Gar nicht. Die eine Sache, die du unter keinen Umständen tun solltest, ist die direkte Manipulation von DOM-Elementen, wie bsw. per document.getElementById. Für das Template ist ausschließlich Angular zuständig und stellt dir dafür Direktiven wie *ngIf, *ngFor, etc. zur Verfügung. Vergiss am besten auch alles, was du jemals in jQuery gelernt hast.

Die Sache mit den drei disabled Buttons ist auch unüblich. Weil man normaler Weise nur einen hat, der bsw. die Validität eines Formulars prüft. Aber du könntest es bei deinem Beispiel doch so machen:
JavaScript:
<button class="btn btn-primary" [disabled]="validateButton(item, i)">Button1</button>

public validateButton(item, i): boolean {
    if ('foo' === 'bar') {
      // your code
      return true;
    }
    return false;
  }
Ich sitze schon so lange dran, aber ich habe einfach keine Idee. Die Frage ist wie ich mit der Funktion ein einzigen Button entweder disablen oder enablen kann. Der Wert für alle wird entweder false oder true. Habe dann versucht deinen Ansatz zu probieren:

Code:
<p *ngFor="let item of items" (click)="statusBtn(item)"> {{ item.status] }} </p>
  <button [disabled]="checkStatus(item, i)">Button1</button>
  <button [disabled]="checkStatus(item, i)">Button2</button>
  <button [disabled]="checkStatus(item, i)">Button3</button>



  status: number;
  statusBtn(item){
    this.status = item.status
  }
  checkStatus(item, i): boolean {
    if(this.status === undefined){
      return false;
    }
    if(this.status === 1){
    }
}
Integer-Typ initialisiert Wert undefined.
In checkStatus frag ich nach ob die lokale Variable status den Wert undefined hat, falls ja, ist jeder button enabled. Dann frag ich, ob die Variable den Wert 1 hat, die statusBtn-Funktion weist der Variable den entsprechenden den Wert zu. Die Frage ist, wie ich für die einzelne Variabeln einen Boolean returnen kann.. Bis hier benutze ich die Parameter item und i überhaupt nicht...

Ich bräuchte nur ein Code-Sample, wo nur ein einziges mal für ein Button ein eigener Boolean-Wert zugewiesen wird. Dann hätte ich die Logik dahinter...
Meine letzte die funktionieren würde, aber nicht schön aussehen würde:
Für jeden Button eine Variable. Je nach item.status Wert ändere ich die Werte der Variablen per If abfragen. Bei mehreren Buttons ziemlich lästig
 

Tronjer

Moderator
Team
Moderator
8 Oktober 2010
5.103
435
83
Berlin
Du musst für die drei [disabled] unterschiedliche Expressions verwenden.
Code:
<div>
  <p *ngFor="let item of items; let i = index" (click)="setButtonStatus(i)"> {{ item.status }} </p>
</div>

<div>
  <button class="btn btn-primary" [disabled]="!buttonStatus(1)">Button1</button>
  <button class="btn btn-primary" [disabled]="!buttonStatus(2)">Button2</button>
  <button class="btn btn-primary" [disabled]="!buttonStatus(3)">Button3</button>
</div>

  public items = [{status: false}, {status: true}, {status: false}];
  public value = 0;

  public setButtonStatus(i): number {
    return this.value = i + 1;
  }

  public buttonStatus(val: number): boolean {
    return this.value === val;
  }
 
Reactions: Tabula_Rasa

Tabula_Rasa

Mitglied
12 Mai 2017
176
2
18
Perfekt! Habe jetzt einen Code geschrieben, um bei einem Klick Buttons willkürlich zu enablen/disablen (mein Ziel)! Funktioniert perfekt! War vom Ansatz her leicht aber kam einfach nicht drauf :). Dein Code hat mich zum Nachdenken angeregt. Wahrscheinlich nicht der beste Code, aber es funktioniert.
Wenn du mal rüberschauen magst:

Code:
<div>
  <p *ngFor="let item of items; let i = index" (click)="setButtonStatus(i)"> {{ item.status }} </p>
</div>
<div>
  <button class="btn btn-primary" [disabled]="!bool1">Button1</button>
  <button class="btn btn-primary" [disabled]="!bool2">Button2</button>
  <button class="btn btn-primary" [disabled]="!bool3">Button3</button>
</div>

  public items = [{status: 1}, {status: 2}, {status: 3}];
  public value = 0;
  public bool1 = true;
  public bool2 = true;
  public bool3 = true;

  public resetBool(){
    this.bool1 = true;
    this.bool2 = true;
    this.bool3 = true; 
  }
 
  public setButtonStatus(i) {    // willkürliches Enablen/Disablen
     this.value = i + 1;
     if(this.value === 1){
       this.resetBool();
        this.bool2 = false;  
        this.bool3 = false;
     } else if (this.value === 2) {
        this.resetBool();
        this.bool1 = false;
        this.bool2 = false;
     } else if (this.value === 3) {
        this.resetBool();
        this.bool1 = false;
        this.bool3 = false;
     }
     }
 

Tronjer

Moderator
Team
Moderator
8 Oktober 2010
5.103
435
83
Berlin
Weshalb 3 unterschiedliche Variablen, wenn es auch mit Funktionsparametern geht. Zumal man in dem Beispiel mit Integers auch über die Buttons iterieren könnte. Dann wird der Code noch kürzer.
HTML:
<div>
  <p *ngFor="let item of items; let i = index" (click)="setButtonStatus(i)"> {{ item.status }} </p>
</div>
<div>
  <button *ngFor="let number of buttons" class="btn btn-primary" [disabled]="!buttonStatus(number + 1)"> Button {{ number + 1 }} </button>
</div>

export class AppComponent {
  public items = [{status: false}, {status: true}, {status: false}];
  public buttons = Array.from(this.items.keys());
  public value = 0;

  public setButtonStatus(i): number {
    return this.value = i + 1;
  }

  public buttonStatus(val: number): boolean {
    return this.value === val;
  }
}
 
Reactions: Tabula_Rasa
Werbung:

Latest posts