0

由于其他帖子,我已经使这个示例的大部分工作,但我仍然遇到一个问题。

如果我抛出错误,错误对话框将按预期工作。如果我抛出 HTTP 错误(包括如果我在管道中捕获错误并返回 throwError(error)),错误对话框也可以工作。但是,如果在尝试显示未定义的对象时抛出了打字稿错误,则错误对话框不会显示来自组件的数据,并且对话框不会关闭。

这是我正在试验的代码。


    import { BrowserModule } from '@angular/platform-browser';
    import { Component, Inject, Injectable, OnInit, ErrorHandler, NgModule, NgZone } from '@angular/core';
    
    import { HttpClientModule } from '@angular/common/http';
    import { HttpClient } from '@angular/common/http';
    
    import { Observable } from 'rxjs';
    
    import { MatDialogModule } from '@angular/material/dialog';
    import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    
    @Component({
      selector: 'app-root',
      template: `
    <div class="content">
    <h1>{{title}}</h1>
    <h3>{{something[0]['text']}}</h3>
    <button (click)="forceFakeError()">Force Fake Error</button>
    <br>
    <button (click)="forceHttpError()">Force HTTP Error</button>
    <br>
    <button (click)="forceTypeError()">Force Type Error</button>
    </div>
    `,
      styles: ['div.content {padding: 25px;}', 'button {margin: 10px}']
    })
    export class AppComponent {
      title = 'dialog-issue';
      something = [{ text: 'This is some test text' }];
      data: any;
    
      constructor(public dialog: MatDialog, private http: HttpClient) {}
    
      forceFakeError() {
          throw(new Error('Fake  eror...'));
      }
    
      forceHttpError() {
        this.http.get<any>('https://garbageinout.io').subscribe({
            next: data => {
                this.data = data;
            },
            error: error => {
                console.error('There was an error!', error);
                throw(error);
            }
        });
      }
    
      forceTypeError() {
        this.something.length = 0;
      }
    }
    
    
    @Injectable({
        providedIn: 'root'
    })
    export class ErrorHandlerService implements ErrorHandler {
    
       handling = false;
    
        constructor(private dialog: MatDialog, private ngZone: NgZone) {}
    
        handleError(error: any) {
            if (this.handling) {
                console.log('errorhandler already handling error message: ' + error.message);
                return;
            }
            this.handling = true;
            console.log('errorhandler error: ', error);
            console.log('errorhandler error name: ' + error.constructor.name);
            const errMsg = error.message ?? 'No message found!';
            console.log('errorhandler error message: ' + error.message);
            this.ngZone.run(() => {
                this.displayErrorMessage('Application Error', errMsg)
                    .subscribe((resp) => {
                        console.log('Response is: ', resp);
                        this.handling = false;
                    });
          });
        }
    
        displayErrorMessage(title: string, msg: string): Observable<string> {
            const dialogRef = this.dialog.open(TestDialog, 
                {width: '400px', disableClose: true, data: { title: title, message: msg}
            });
            return dialogRef.afterClosed();
        }
    }
    
    
    export interface ErrorData {
       title: string;
       message: string;
    }
    
    @Component({
      selector: 'app-error',
      template: `
    <div>
    <h1 mat-dialog-title>{{title}}</h1>
    <div mat-dialog-content>
      <p>Click OK to continue, or click on the "Click here"
         link to restart the app.</p>
      <p>Message: {{msg}}</p>
      <p>{{dateTime()}}</p>
      <p><a href="/index">Click here</a> to restart app</p>
    </div>
    <button mat-raised-button (click)="onClick()">OK</button>
    </div>
    `,
      styles: ['button { margin: 5 }']
    })
    export class TestDialog implements OnInit {
        title: string = 'Fake Title';
        msg: string = 'Fake string';
    
        constructor(public dialogRef: MatDialogRef<TestDialog>,
                @Inject(MAT_DIALOG_DATA) public data: ErrorData) {
            this.title = data.title;
            this.msg = data.message ?? 'Message not provided...';
        }
    
        ngOnInit() {
            console.log('error dialog, title: ', this.title, ', msg: ', this.msg);
        }
    
        dateTime(): string {
            return new Date().toString();
        }
    
        onClick() {
            console.log('entering error dialog onClick event');
            this.dialogRef.close('OK!');
        }
    }
    
    
    @NgModule({
      declarations: [
        AppComponent,
        TestDialog
      ],
      imports: [
        BrowserModule,
        BrowserAnimationsModule,
        MatDialogModule
      ],
      exports: [
        HttpClientModule,
        MatDialogModule
      ],
      providers: [
          { provide: ErrorHandler, useClass: ErrorHandlerService }
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

我的环境是:


    Angular CLI: 13.2.2
    Node: 16.13.0
    Package Manager: npm 8.4.1
    OS: darwin arm64
    
    Angular: 13.2.1
    ... animations, cdk, common, compiler, compiler-cli, core, forms
    ... material, platform-browser, platform-browser-dynamic, router
    
    Package                         Version
    ---------------------------------------------------------
    @angular-devkit/architect       0.1302.2
    @angular-devkit/build-angular   13.2.2
    @angular-devkit/core            13.2.2
    @angular-devkit/schematics      13.2.2
    @angular/cli                    13.2.2
    @schematics/angular             13.2.2
    rxjs                            7.5.2
    typescript                      4.5.5

我正在使用命令“ng serve --ssl --configuration production”来执行。

预先感谢您对如何解决此问题的任何见解。

4

1 回答 1

0

那是因为没有Error提出。你something是一个数组并且有一个长度属性。当然它应该是只读的,但 javascript 无论如何都会执行它——尽管它对长度属性的值没有影响。

您可以直接在浏览器开发控制台中对其进行测试。只需键入并输入:

[].length = 0;

不会引发错误。

我想你的处理程序应该正确处理这样的事情:

this.something.unknownProperty.anotherProperty = 0;

由于unknownProperty将返回未定义,javascript 无法执行该语句。它无法anotherProperty从未定义中解决。这会引发错误。

于 2022-02-08T19:37:24.950 回答