【问题标题】:Angular2: Modal Dialog does not catch key-eventsAngular2:模态对话框不捕捉关键事件
【发布时间】:2017-09-09 11:44:43
【问题描述】:

我正在关注modal dialog 和下面的 cmets 的解决方案。由于它们太多了,为了清楚起见,我决定制作一个新的 q 我有改编版:

import { Component, ViewChild } from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap';

@Component({
  selector: 'app-modal',
  template: `
  <div #myModal class="modal fade"   tabindex="-1" [ngClass]="{'in': visibleAnimate}"
       [ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}">
    <div class="modal-dialog">
      <div class="modal-content" (click)="$event.stopPropagation();">
        <div class="modal-header">
          <ng-content select=".app-modal-header"></ng-content>
        </div>
        <div class="modal-body">
          <ng-content select=".app-modal-body"></ng-content>
        </div>
        <div class="modal-footer">
          <ng-content select=".app-modal-footer"></ng-content>
        </div>
      </div>
    </div>
  </div>
  `
})
export class ModalComponent {
  @ViewChild('myModal') public myModal: ModalDirective;

  public visible = false;
  private visibleAnimate = false;

  public show(): void {
    this.visible = true;
    setTimeout(() => this.visibleAnimate = true);
    document.body.className += ' modal-open';
  }

  public hide(): void {
    this.visibleAnimate = false;
    document.body.className = document.body.className.replace('modal-open', '');
    setTimeout(() => this.visible = false, 300);
  }

  public onContainerClicked(event: MouseEvent): void {
    if ((<HTMLElement>event.target).classList.contains('modal')) {
      this.hide();
    }
  }
}

我现在使用这种方法的主要问题是:

  1. 键盘事件不会在模态对话框中捕获,而是发送到后面。如何预防?
  2. 如评论部分所问:如何多次叠加对话框?即有一个模态对话框,例如编辑,而不是顶部的附加错误通知。这出现在后台...

编辑: 在检查了几个来源后,我发现了以下内容:

我需要安装ngx-bootstrap,添加app.module.ts

import { ModalModule } from 'ngx-bootstrap';
...
@NgModule({
  imports: [
    ...
    ModalModule
  ],

并添加systemjs.config.js

// ngx-bootstrap
        'ngx-bootstrap' : {
            format : 'cjs',
            main : 'bundles/ngx-bootstrap.umd.js',
            defaultExtension : 'js'
        },
        'moment' : {
            main : 'moment.js',
            defaultExtension : 'js'
        },

通过上述更改(以及更新的代码),我仍然无法在第一个模式对话框之前获得第二个模式对话框。提示?

【问题讨论】:

    标签: angular modal-dialog


    【解决方案1】:

    以下代码

    import { Component, ViewChild, Input } from '@angular/core';
    
    @Component({
      selector: 'app-modal',
      template: `
      <div class="modal fade"   tabindex="-1" [ngClass]="{'in': visibleAnimate}"
           [ngStyle]="getStyle()">
        <div class="modal-dialog">
          <div class="modal-content" (click)="$event.stopPropagation();">
            <div class="modal-header">
              <ng-content select=".app-modal-header"></ng-content>
            </div>
            <div class="modal-body">
              <ng-content select=".app-modal-body"></ng-content>
            </div>
            <div class="modal-footer">
              <ng-content select=".app-modal-footer"></ng-content>
            </div>
          </div>
        </div>
      </div>
      `
    })
    export class ModalComponent {
    
      public visible = false;
      private visibleAnimate = false;
      @Input() public zIndex = 500;
    
      public show(): void {
        this.visible = true;
        setTimeout(() => this.visibleAnimate = true);
        document.body.className += ' modal-open';
      }
    
      public hide(): void {
        this.visibleAnimate = false;
        document.body.className = document.body.className.replace('modal-open', '');
        setTimeout(() => this.visible = false, 300);
      }
    
      public getStyle() {
        return {
          'z-index': this.zIndex,
          'display': this.visible ? 'block' : 'none',
          'opacity': this.visibleAnimate ? 1 : 0
        }
      };
    
    }
    

    允许我在下一个模板中设置 zIndex,例如 &lt;app-modal [zIndex]=1000&gt; - 这非常很好

    解决了这个问题

    【讨论】:

      【解决方案2】:

      我是那篇文章的原作者,抱歉耽搁了,也许还为时不晚:)

      1) 不太清楚你在这里的意思 2) 我已经更新了该答案,以便能够一次显示多个模式

      【讨论】:

      • 不幸的是,这不起作用。第二个模态对话框将出现在第一个对话框的背景中:-/
      • 嗯,我没有遇到这个问题。也许您可以尝试使用 z-index?换句话说,每个模态都有一个稍高的 z-index。
      • 如果我尝试使用 z-index 遵循您的提示,即 stackoverflow.com/questions/19305821/multiple-modals-overlay/…,我会迷失样式和/或如何动态计算它(即,如果我在顶部 ==> 如何/增加什么?)
      • 是的,我正要考虑应用那篇文章中的建议,但无论如何我来对了。我已经在我原来的帖子中添加了一个 plunkr,你应该可以看到它。我注意到模板中模态的顺序很重要。我已经在 Chrome、Firefox、Edge 和 IE11 上对此进行了测试(您可能使用的是其他浏览器吗?:)
      • 我玩了一下并更改了您的示例以简化使用...。见上文...老实说,不知道在哪里更正确地更新它 - 在这里或在您的帖子中;- ) 随时更新您的...
      【解决方案3】:

      您没有包含ModalDirective,这是您的键盘事件无法识别的原因

      @Component({
        selector: 'app-modal',
        template: `/////////////////////
        <div class="modal fade" #myModal tabindex="-1" [ngClass]="{'in': visibleAnimate}"
             [ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}">
          <div class="modal-dialog">
            <div class="modal-content" (click)="$event.stopPropagation();">
              <div class="modal-header">
                <ng-content select=".app-modal-header"></ng-content>
              </div>
              <div class="modal-body">
                <ng-content select=".app-modal-boddocument.body.className = document.body.className.replace('modal-open', ''); y"></ng-content>
              </div>
              <div class="modal-footer">
                <ng-content select=".app-modal-footer"></ng-content>
              </div>
            </div>
          </div>
        </div>
        `
      })
      export class ModalComponent {
      @ViewChild('myModal') public myModal:ModalDirective; ////
        public visible = false;
        private visibleAnimate = false;
      
        public show(): void {
          this.visible = true;
          setTimeout(() => this.visibleAnimate = true);
          document.body.className += ' modal-open';
        }
      
        public hide(): void {
          this.visibleAnimate = false;
          document.body.className = document.body.className.replace('modal-open', ''); 
          setTimeout(() => this.visible = false, 300);
        }
      }
      

      有关如何在整个应用程序中重用模态组件的更多信息,请访问 answer

      【讨论】:

      • 抱歉回复晚了。我现在对其进行测试,但我不确定完整的样本应该是什么样子。 ModalDirective 将从 ngx-bootstap 导入。在 app.module.ts 中,我导入了ModalDirective(是否需要ModalModule?)并尝试关注您的链接stackoverflow.com/a/42633720/325868。但不知何故,Chrome 在加载 ngx-bootstrap 时遇到问题 - 即我得到一个 Error - unexpected token &lt; ... zone.js:365.... Evaluating http://..../ngx-bootstrap... - 有什么想法吗?
      • 我想出了如何修复我的最后一个问题 - 但问题仍然存在 - 见上文
      • 我玩了一圈,发现可以采用最初的方法。尽管如此,额外的安装是学习依赖关系的好习惯;-)
      猜你喜欢
      • 1970-01-01
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-21
      • 2011-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多