如何将函数从模态传递到具有差异的 parent 组件

How to pass a function from modal to parent component with differences

我看过一些示例,因此标题添加了 'with differences'。

在示例中,模态加载到 parent 组件的自定义标记中:即

  template: `
  <div class="container-fluid">
    <template ngbModalContainer></template>
    <ngbd-modal-component (notifyParent)="getNotification($event)"></ngbd-modal-component>
  </div>
  `

但是我没有自定义标签。 Modal 完美加载到 body 我想要的位置。

这里是home.component.html

<nav class="navbar navbar-dark bg-primary navbar-expand-md justify-content-between fixed-top">
    <div class="navbar-brand mr-auto">
                <a class="navbar-brand" title="appChoser" href="appChooser" target="_self" >
                    <span class="glyphicon glyphicon-menu"></span>
                </a>

            <a class="navbar-brand logo" title="" routerLink="/dashboard" rel="home"></a>
        </div>
        <button type="button" class="navbar-toggler" data-toggle="collapse" (click)="isCollapsed = !isCollapsed"  [attr.aria-expanded]="!isCollapsed" data-target="#bs-navbar-collapse" >
                <span class="sr-only">Toggle navigation</span>
                <span class="glyphicon glyphicon-ellipsis"></span>
        </button>


        <div class="collapse navbar-collapse" [ngbCollapse]="isCollapsed" id="bs-navbar-collapse">
             <ul class="nav navbar-nav">
                 <li class="navbar-item">
                     <a class="nav-link" ui-sref="simListView" ui-sref-active="active" title="SIM list"><span class="glyphicon glyphicon-icons2"></span><span class="d-md-none d-lg-inline">Sim List</span></a>
                </li>
                <li class="navbar-item">
                            <a class="nav-link" ui-sref="reportsView" title="Reports"><span class="glyphicon glyphicon-chart-bars"></span><span class="d-md-none d-lg-inline">Reports</span></a>
                </li>

                    <li class="navbar-item" >
                        <a class="nav-link" routerLink="/hierarchy-mgmt" title="Show Managed Accounts" ><span class="glyphicon glyphicon-group-work"></span><span class="d-md-none d-lg-inline">Managed Accounts</span></a>
                    </li>

            </ul>
            <ul class="nav navbar-nav ml-auto">
                <li class="navbar-item" id="about_top_menu_button">
                    <a class="nav-link" href="javascript:void(0)" target="_self" (click)="open();" title="About Estate Management"><span
                            class="glyphicon glyphicon-ark-info-circle"></span><span class="d-md-none d-lg-inline">About</span></a>
                </li>

                <li class="navbar-item" >
                    <a class="nav-link"   title="Frequently Asked Questions and much more"><span
                            class="glyphicon glyphicon-question-circle"></span><span class="d-md-none d-lg-inline">Help</span></a>
                </li>

                <li>
                    <div class="d-sm-none" id="loggedinas">Welcome,<br/>User</div>
                </li>
                <li ngbDropdown class="dropdown" >
                    <a  id="userDropdown" href="javascript:void(0)" class="nav-link dropdown-toggle"  ngbDropdownToggle>
                        <span class="glyphicon "></span>
                        <span class="caret"></span>
                    </a>
                    <div ngbDropdownMenu class="dropdown-menu dropdown-menu-right" aria-labelledby="userDropdown">
                        <div class="identity-cell"  id="notify_identity" >Identity: {{user}}</div>
                        <a class="dropdown-item" routerLink="/assume-id" title="Assume another user&#39;s identity">Assume Identity</a>
                        <a class="dropdown-item" routerLink="/my-profile" title="My user account details">My Profile</a>
                        <a class="dropdown-item" href="javascript:void(0)" (click)="logout();" title="Log out from Estate Management">Logout</a>
                    </div>
                </li>
            </ul>
        </div><!-- navbar collapse -->
</nav>

所以我不确定我需要做什么。我发出我认为来自这样的模态组件的函数。

import {Component,Output, EventEmitter, Input} from '@angular/core';

import {NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'ngbd-modal-content',
  template: `
    <div (processYes)="processYes();" class="modal-header">
      <h4 class="modal-title">Hi there!</h4>
      <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
        <span aria-hidden="true">&times;</span>
      </button>
    </div>
    <div class="modal-body">
      <p>Hello, {{name}}!</p>
      <ng-template #tipContent>{{tip}}</ng-template>
      <a href="javascript:void(0)"><span [ngbTooltip]="tipContent" placement="right"  class="glyphicon glyphicon-ark-info-circle">Info</span></a>
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-outline-dark" (click)="activeModal.close()">No</button>
      <button type="button" class="btn btn-primary" (click)="yes()">Yes</button>
    </div>
  `
})
export class NgbdModalContent {
  @Input() name;
  @Input() tip;
  @Output() processYes: EventEmitter<any> = new EventEmitter();
  
   yes(){
        console.log('Notify clicked...');
        this.processYes.emit();
        this.activeModal.close('Yes click');
    }
 

  constructor(public activeModal: NgbActiveModal) {
    
    
  }
}

我的主页组件(目前只是导航)应该从 'Yes' 按钮接收功能并用它做一些事情,主要是 运行 本身的一个新功能。这是代码:

import { Component } from '@angular/core';
import { NgbdModalContent } from './modal.component';
import { NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';


@Component({
  selector: 'my-app',
  templateUrl:'src/home.content.html' 
})


export class HomeComponent {
  
  processYes(){
    console.log('run a new function of this component here');
  }
  
 constructor(private modalService: NgbModal) {}

  open() {
    const modalRef = this.modalService.open(NgbdModalContent);
    modalRef.componentInstance.name = 'World';
    modalRef.componentInstance.tip = 'Well this is a tooltip';
  
    }

  
}

最短的路是什么?如果 home 组件实际上可以在打开它或输入数据的示例中引用模态组件,为什么还需要发射和输出模块?

这里也是plunker版本。 https://plnkr.co/edit/ZcD8NnHe0RqlwTDOA5Pz?p=preview

在 open 函数外调用 emitResponse

open() {
  const modalRef = this.modalService.open(NgbdModalContent);
  modalRef.componentInstance.name = 'World Welcome';
  modalRef.componentInstance.emitData.subscribe(($e) => {
    this.recive($e);
  })
}

recive(event) {
  console.log('event', event);
}

像这样尝试:

我刚刚提到了你的 plunker 代码,如下所示:

model.compoent.ts

import {Component, Input, Output, EventEmitter} from '@angular/core';

import {NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'ngbd-modal-content',
  template: `
    <div class="modal-header">
      <h4 class="modal-title">Hi there!</h4>
      <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
        <span aria-hidden="true">&times;</span>
      </button>
    </div>
    <div class="modal-body">
      <p>Hello, {{name}}!</p>
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-outline-dark" (click)="add()">Emit</button>
      <button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
    </div>
  `
})
export class NgbdModalContent {
  @Input() name;
  @Output() emitData = new EventEmitter();
  constructor(public activeModal: NgbActiveModal) {}

  add() {
    this.emitData.next('Hello world');
  }
}

和home.component.ts

open() {
    const modalRef = this.modalService.open(NgbdModalContent);
    modalRef.componentInstance.name = 'World';
    modalRef.componentInstance.emitData.subscribe(($e) => {
      console.log('$e', $e);
    })
  }

Why there is emit and output modules needed if home component can actually reference to modal component anyway in the example of opening it or putting in data?

@Input@Output 都是单向绑定。

What is the shortest way?

通过在分配给 EventEmitterModalComponent 中设置您的 @Output,您已经在正确的轨道上了。您在通过 HomeComponent 模板传递发出的事件方面也处于正确的轨道上,但是您需要确保变量和函数名称与您的代码匹配,如下所示:

(processYes)="processYes()"

赋值的左侧是您的 @Output 变量,赋值的右侧是您的 HomeComponent.

中的函数

如果你想运行组件中的一些方法用于创建模式,你可以像下面的代码那样做。

modalRef.content.yourMethod();