hmm: Angular8 MatDialog

Hi,

ich habe MatDialog wie in diesem Beispiel beschrieben benutzt:

https://material.angular.io/components/dialog/examples

Leider wird mir das Dialog Fenster unten in meinem Hauptfenster angezeigt und der Bildschirmhintergrund wird leider nicht verdunkelt. Mit welcher Technik ziehe ich das Dialogfenster in die Mitte des Bildschirms und wie dunkle ich den Hintergrund ab?

Ich stelle die Frage, weil ich vermute, dass es dafür einen Weg gibt, bei dem ich nicht alles selbst programmieren muss.

akzeptierte Antworten

  1. @@hmm

    ich habe MatDialog wie in diesem Beispiel beschrieben benutzt:

    https://material.angular.io/components/dialog/examples

    Schlecht. Beispiele im Web erstellt von Entwicklern, denen die Grundlagen von HTML fehlen. 😡

    Das Eingabefeld sollte ein zugehöriges label haben. Placeholder sind keine Label. Siehe Fußnoten

    Ich stelle die Frage, weil ich vermute, dass es dafür einen Weg gibt, bei dem ich nicht alles selbst programmieren muss.

    Ja, „einen modalen Dialog sollte man nicht selbst bauen, wenn man nicht genau weiß, was da alles zu beachten ist.“ Siehe dortige Links.

    LLAP 🖖

    --
    „Man kann sich halt nicht sicher sein“, sagt der Mann auf der Straße, „dass in einer Gruppe Flüchtlinge nicht auch Arschlöcher sind.“
    „Stimmt wohl“, sagt das Känguru, „aber immerhin kann man sich sicher sein, dass in einer Gruppe Rassisten nur Arschlöcher sind.“

    —Marc-Uwe Kling
    1. Tach!

      ich habe MatDialog wie in diesem Beispiel beschrieben benutzt:

      https://material.angular.io/components/dialog/examples

      Schlecht. Beispiele im Web erstellt von Entwicklern, denen die Grundlagen von HTML fehlen. 😡

      Erstaunlich, was du alles über Leute weißt, die du nicht kennst.

      Das Eingabefeld sollte ein zugehöriges label haben. Placeholder sind keine Label. Siehe Fußnoten

      Das Label ist da. Im Code, der von mat-form-field oder matInput erzeugt wird.

      dedlfix.

      1. @@dedlfix

        Schlecht. Beispiele im Web erstellt von Entwicklern, denen die Grundlagen von HTML fehlen. 😡

        Erstaunlich, was du alles über Leute weißt, die du nicht kennst.

        Ein Blick in den Code sagt genug.

        Das Label ist da. Im Code, der von mat-form-field oder matInput erzeugt wird.

        In der Tat.

        Auf den Unsinn, ein für etwas völlig anderes gedachtes HTML-Attribut dazu zu missbrauchen, per JS ein label zu erstellen, kann aber auch nur ein JS-Entwickler kommen, der HTML nicht als Grundlage, sondern lediglich als störendes Beiwerk ansieht.

        Die Komponente krankt dennoch daran, dass die Beschriftung initial im Eingabefeld angezeigt wird und damit schlecht von einer getätigten Eingabe zu unterscheiden ist. Nicht machen, Kinder!

        LLAP 🖖

        --
        „Man kann sich halt nicht sicher sein“, sagt der Mann auf der Straße, „dass in einer Gruppe Flüchtlinge nicht auch Arschlöcher sind.“
        „Stimmt wohl“, sagt das Känguru, „aber immerhin kann man sich sicher sein, dass in einer Gruppe Rassisten nur Arschlöcher sind.“

        —Marc-Uwe Kling
        1. Tach!

          Auf den Unsinn, ein für etwas völlig anderes gedachtes HTML-Attribut dazu zu missbrauchen, per JS ein label zu erstellen, kann aber auch nur ein JS-Entwickler kommen, der HTML nicht als Grundlage, sondern lediglich als störendes Beiwerk ansieht.

          Angular Material, abgeleitet von Material Design, beides entwickelt von Google, alles nur JS-Entwickler ...

          Man kann aber eine gewisse Konsistenz darin sehen. Die Beschriftung ist in Form von Platzhaltern vorgesehen, die sich bei einer Eingabe nach oben hin verziehen und zum Label werden. Ungeachtet davon, kann man ein separates Label definieren, das sich vom Platzhalter unterscheidet.

          Abgesehen davon ist das Verstecken von Komplexität hinter einer einfacher verwendbaren Funktion oder Komponente eine bewährte Vorgehensweise. Warum sollte man das nicht auch auf ein HTML-ähnliches Template-System anwenden? Siehe auch Web Components.

          Die Komponente krankt dennoch daran, dass die Beschriftung initial im Eingabefeld angezeigt wird und damit schlecht von einer getätigten Eingabe zu unterscheiden ist. Nicht machen, Kinder!

          Gefällt mir auch nicht, deswegen nehm ich es nicht für eigene Projekte.

          Es ist jedoch nicht so, dass sich die Entwickler von Material Design keine Gedanken zu dem machen, was sie da entwickeln. Beispiel.

          dedlfix.

        2. Auf den Unsinn, ein für etwas völlig anderes gedachtes HTML-Attribut dazu zu missbrauchen, per JS ein label zu erstellen, kann aber auch nur ein JS-Entwickler kommen, der HTML nicht als Grundlage, sondern lediglich als störendes Beiwerk ansieht.

          Das ist laut Dokumentation eine historisch bedingte Altlast und nicht der empfohlene Lösungsweg:

          In the legacy version of the <mat-form-field> (one that has no appearance attribute or has appearance="legacy") if a label is not specified, the placeholder attribute on the form control is promoted to a label.

  2. Tach!

    ich habe MatDialog wie in diesem Beispiel beschrieben benutzt:

    https://material.angular.io/components/dialog/examples

    Leider wird mir das Dialog Fenster unten in meinem Hauptfenster angezeigt und der Bildschirmhintergrund wird leider nicht verdunkelt.

    Dann fehlt dir vermutlich noch etwas. Der Dialog braucht jedenfalls noch Dinge aus dem cdk-Paket. Öffne das Beispiel doch mal in StackBlitz (Button rechts oben in der Ecke) und schau, ob dir eins der Pakete aus package.json fehlt, vielleicht @angular/cdk.

    dedlfix.

    1. kann es sein das ich css per MatDialogConfig setzen muss?

      die packete habe ich.

      1. Tach!

        kann es sein das ich css per MatDialogConfig setzen muss?

        Hast du eins der Themes importiert? Alle Schritte von Getting Started ausgeführt?

        dedlfix.

    2. die haben in einer scss datei das hier:

      @import '~@angular/material/prebuilt-themes/deeppurple-amber.css';

      kann ich das einfach in meine css datei packen?

      1. Tach!

        die haben in einer scss datei das hier:

        @import '~@angular/material/prebuilt-themes/deeppurple-amber.css';

        kann ich das einfach in meine css datei packen?

        Ein Angular-Projekt hat üblicherweise mehrere CSS-Dateien. Schreib das am besten wie im Beispiel in die globale CSS-Datei. Wenn man Angular Material verwendet, baut man normalerweise die gesamte Oberfläche damit und nimmt nicht nur Teile daraus. Deswegen braucht man das Theme auch global.

        dedlfix.

        1. der import von dem css hats gebracht, danke.

          wo wir gerade beim thema sind. wenn ich im dialog auf einen button drücke, wird eine POST REQUEST abgeschickt. solange der POST auf pending steht hätte ich gerne einen ladestreifen oder ähnliches und nach dem pending einen kurzen dialog wo ich dem nutzer sage ob das geklappt hat. bietet mir angular sowas, falls ja wie heißt das modul?

          1. Tach!

            wo wir gerade beim thema sind. wenn ich im dialog auf einen button drücke, wird eine POST REQUEST abgeschickt. solange der POST auf pending steht hätte ich gerne einen ladestreifen oder ähnliches und nach dem pending einen kurzen dialog wo ich dem nutzer sage ob das geklappt hat. bietet mir angular sowas, falls ja wie heißt das modul?

            Angular bietet da nichts direkt an. Auch Angular Material nicht. Aber du kannst vor dem Absenden einen Dialog einblenden mit Progress Spinner oder ähnlichem drin. Wenn der Request fertig ist (auch den Fehlerfall beachten) kannst du den Dialog entfernen.

            Wenn die Sache automatisiert stattfinden soll, dann kannst du einen HttpInterceptor erstellen. Zum Beispiel so:

            import { Injectable } from '@angular/core';
            import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
            import { Observable } from 'rxjs';
            import { finalize } from 'rxjs/operators';
            
            @Injectable()
            export class LoadingInterceptor implements HttpInterceptor {
            
                intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
                    setTimeout(() => this.showSpinner());
            
                    return next.handle(req).pipe(
                        finalize(() => {
                            setTimeout(() => this.hideSpinner());
                        })
                    );
                }
            
                private showSpinner() { ... }
                private hideSpinner() { ... }
            }
            

            Die setTimeout() ohne Zeit dienen dazu, das Anzeigen und Verstecken an die Javascript-Event-Loop anzuhängen, weil der Browser sonst mitunter zu busy ist, sich mit dem Dialog zu beschäftigen.

            Der Interceptor muss noch ins System eingebunden werden, aber da sagt dir das Angular-Handbuch, wie das geht.

            dedlfix.

            1. super, danke.

              kann ich eine Instanz bei MatDialog open() übergeben?

              MatDialog open() wird bei mir in meiner Fenster.ts aufgerufen und öffnet mir eine Komponente mit InstanzzuweisenDialog.ts, in dieser .ts Datei würde ich gerne eine Variable seten, welche als private in Fenster.ts definiert ist. Dazu würde ich gerne ein Objekt bzw. die Instanzdazu übergeben. Geht das bei MatDialog open()?

              1. Tach!

                kann ich eine Instanz bei MatDialog open() übergeben?

                Siehe Dokumentation: Sharing data with the Dialog component.

                dedlfix.

                1. stimmt, steht in der doku, danke.

                  <h1 mat-dialog-title>Release verwerfen?</h1>
                  <div mat-dialog-content>
                    <div>
                      <p>Möchten Sie das ausgewählte Release wirklich verwerfen?</p>
                  
                      <mat-form-field [style.fontSize]="500">
                        <mat-label>Kommentar</mat-label>
                        <textarea required  [(ngModel)]="kommentar"
                                  matInput
                                  cdkTextareaAutosize
                                  #autosize="cdkTextareaAutosize"
                                  cdkAutosizeMinRows="3"
                                  cdkAutosizeMaxRows="8"></textarea>
                      </mat-form-field>
                    </div>
                  </div>
                  
                  <div mat-dialog-actions>
                    <button mat-raised-button (click)="this.onNoClick()">ABBRECHEN</button>
                    <button mat-raised-button (click)="this.verwerfen()" cdkFocusInitial>RELEASE VERWERFEN</button>
                  </div>
                  

                  wie verhindere ich, dass ein klick auf verwerfen ohne vorheriges ausfüllen der textarea funktioniert? wird mir da von angular etwas angeboten?

                  1. und die beiden button werden leider mit keinem css versehen, im stackblitz beispiel sehen die anders aus.

                    1. Tach!

                      und die beiden button werden leider mit keinem css versehen, im stackblitz beispiel sehen die anders aus.

                      Dann fehlt wohl das Theme oder ... keine Ahnung, bin schlecht im Hellsehen.

                      dedlfix.

                  2. Tach!

                    wie verhindere ich, dass ein klick auf verwerfen ohne vorheriges ausfüllen der textarea funktioniert? wird mir da von angular etwas angeboten?

                    Das übliche, wie disabled setzen, oder im Click-Handler eine Fallunterscheidung einbauen. Auf disabled setzen, ist meist keine gute Idee, wenn der Anwender nicht sieht, warum das disabled ist, oder wie man den in den benutzbaren Zustand bekommt.

                    dedlfix.