0

This plunker should open up a modal when the button is pressed. I have extended the existing ngx-modal but it throws error: Cannot read property 'nativeElement' of undefined.

Having looked at the console this is because "modalRoot" should be programatically assigned as a ViewChild handler for the modal. It doesn't seem to get defined when extended even though I've added the super() to my constructor, any ideas?

Plunker that shows issue

    //our root app component
import {Component, NgModule, HostListener, ElementRef} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {ModalModule} from "ngx-modal";
import { Modal } from "ngx-modal";

@Component({
    selector: 'ext-ngx-modal', 
    template: `<ng-content></ng-content>`,
})
export class NgxModalComponent extends Modal {
    constructor() {
        super();
    }

    openExt():void {
      this.open();
    }

    @HostListener('document:keydown', ['$event'])
    onkeydown(ev: KeyboardEvent) {
        console.log("this.isOpened: " + this.isOpened;
    }
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}} I am </h2>
      <div class="row container-fluid">
        <button (click)="myExtNgxModal.openExt()"> open my modal</button>
        <ext-ngx-modal #myExtNgxModal>
          <modal>
              <modal-header>
                  <h1>Modal header</h1>
              </modal-header>
              <modal-content>
                  Press F12 see the console...press a key while modal open
              </modal-content>
              <modal-footer>
                  <button class="btn btn-primary" (click)="myModal.close()">close</button>
              </modal-footer>
          </modal>
        </ext-ngx-modal>
      </div>
    </div>
  `,
})
export class App {
  name:string;
  constructor() {
    this.name = 'Angular2'
  }
}

@NgModule({
  imports: [ BrowserModule, ModalModule ],
  declarations: [ App, NgxModalComponent ],
  exports: [ NgxModalComponent ],
  bootstrap: [ App ]
})
export class AppModule {}
4

1 回答 1

1

仅扩展类 - 不同的模板

当您的NgxModalComponent组件扩展Modal组件时,它将像您想象的那样继承代码。

问题是您正在用自己的模板覆盖它。这是一个问题,因为您继承的某些代码依赖于原始Modal组件的模板。

以下是源代码中的一个示例,其中Modal获取了对模板中元素的访问权限:

/***** FROM NGX-MODAL SOURCE *****/
@ViewChild("modalRoot")
public modalRoot: ElementRef;

当它调用时open()它在内部使用这个引用来设置focus它的原生元素

/***** FROM NGX-MODAL SOURCE *****/
window.setTimeout(() => this.modalRoot.nativeElement.focus(), 0);

由于您没有相同template且没有名为modalRoot的元素,因此它将失败。

解决方案

使用ContentChild文档

一种解决方案是用于ContentChild获取对Modal包装在模板中的引用。yurzui在此评论中发布了一个显示此内容的plunkeryurzui创建了这个 plunker,这不归功于我!)。

他正在做的是获取模态引用并调用open()嵌入式Modal实例上的方法。

@ContentChild(Modal) modal: Modal;

  openExt():void {
    this.modal.open();
  }

重新思考你的方法

另一种选择是重新考虑是否真的需要扩展此模式的方法以及正确的前进方式。但这取决于你:)

我希望这有帮助!

于 2017-06-23T07:45:22.357 回答