扩展后的Ngx-Modal'未定义的NativeElement' Angular 2

时间:2017-06-22 16:04:21

标签: angular typescript inheritance ngx-modal

按下按钮时,此弹射器应打开模态。我已经扩展了现有的ngx模式,但它会抛出错误:无法读取属性' nativeElement'未定义的。

  

查看控制台后,这是因为" modalRoot"应该以编程方式指定为模式的ViewChild处理程序。即使我已经将super()添加到我的构造函数中,任何想法,它似乎都没有在扩展时定义?

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 {}

1 个答案:

答案 0 :(得分:1)

仅扩展类 - 不同的模板

当您的NgxModalComponent组件扩展Modal组件时,它将像您要成像一样继承代码。

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

以下是来自the source code的示例,其中Modal可以访问模板中的元素:

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

当它调用open()it's using this reference internally在其原生元素上设置focus时:

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

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

解决方案

使用ContentChild docs

一种解决方案是使用ContentChild来获取对模板中包含的Modal的引用。 yurzui 发布了一个plunker,在this comment中显示了这一点( yurzui 创建了这个plunker,对我没有任何好处!)。

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

@ContentChild(Modal) modal: Modal;

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

重新思考您的方法

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

我希望这有帮助!