Angular2 bootstrap模式与子组件

时间:2017-12-12 18:41:47

标签: angular bootstrap-modal angular2-template ng-bootstrap ng-modal

我想使用带有子组件的Ng Bootstrap Modal作为模态体。 我不确定如何实现这一目标......

export class ParentComponent {
   @ViewChild("modal") private engineModal: TemplateRef<any>;
   dialog: NgbModalRef | null;

   constructor(private modalService: NgbModal) {}

   openModal(): void {
      this.dialog = this.modalService.open(this.engineModal);
   }

   cancelModal (): void {
      if ( this.dialog ) {
         this.dialog.dismiss();
         this.dialog = null;
      }
   }
}

并且,我知道这是错的,但最终我还想做这样的事情,

<ng-template #modal>
  <app-child-component></app-child-component>
</ng-template>

子组件有很多输入和输出变量,那么这里最好的方法是什么?

3 个答案:

答案 0 :(得分:1)

您可以尝试内容投影(熟悉AngularJS的人进行翻译)。

您可以像这样创建自定义模式:

<div class="modal-body"> 
  <ng-content select="child-body"></ng-content>
</div>

您可以根据此自定义模式

创建子模态
<custom-modal>
  <child-body>
     {...}
  </child-body>
</custom-modal>

基本上你在child-body标签之间写的是它将被复制到ng-content位置的custom-modal元素中。

在此处阅读有关内容投影的更多信息:

https://angular-2-training-book.rangle.io/handout/components/projection.html

希望这有帮助!

答案 1 :(得分:0)

你好是的,你是对的,你必须使用ViewChild来做到这一点,然后创建一个使用open函数的open函数,如下所述:

    import shapeless.labelled.{FieldType, field}
    import shapeless.{::, HList, HNil, LabelledGeneric, Lazy, Witness}

    object FieldParser {
  trait ValParser[A] {
    def parse(str:String): A
  }

  trait FieldParser[A] {
    def parse: A
  }

  type FT[A, B] = FieldType[A, B]
  type ListField[K <: Symbol, A] = FieldType[K, List[A]]
  type FP[A] = FieldParser[A]
  type Args = (List[String],Map[String, Int])
  type Named[K <: Symbol] = Witness.Aux[K]

  private def create[A](thunk: A): FP[A] = {
    new FP[A] {
      def parse: A = thunk
    }
  }

  def apply[A](implicit st: Lazy[FP[A]]): FP[A] = st.value

  implicit def genericParser[A, R <: HList](implicit generic: LabelledGeneric.Aux[A, R], parser: Lazy[FP[R]], args:Args): FP[A] = {
    create(generic.from(parser.value.parse))
  }

  implicit def hlistParser[K <: Symbol, H, T <: HList](implicit hParser: Lazy[FP[FT[K, H]]], tParser: FP[T]): FP[FT[K, H] :: T] = {
    create {
      val hv = hParser.value.parse
      val tv = tParser.parse
      hv :: tv
    }
  }

  implicit def standardTypeParser[K <: Symbol, V:ValParser](implicit named: Named[K], args:Args): FP[FieldType[K, V]] = {
    create(field[K](implicitly[ValParser[V]].parse(findArg)))
  }

  implicit def optionParser[V](implicit valParser:ValParser[V]): ValParser[Option[V]] = new ValParser[Option[V]]{
    def parse(str:String):Option[V] = {
      str.isEmpty match {
        case true => None
        case false => Some(valParser.parse(str))
      }
    }
  }

  implicit def listParser[V](implicit valParser:ValParser[V]): ValParser[List[V]] = new ValParser[List[V]]{
    def parse(str:String):List[V] = {
      str.isEmpty match {
        case true => Nil
        case false => str.split(",").map(valParser.parse).toList
      }
    }
  }

  implicit def doubleParser: ValParser[Double] = new ValParser[Double]{
    def parse(str:String):Double = str.toDouble
  }

  implicit def intParser: ValParser[Int] = new ValParser[Int]{
    def parse(str:String):Int = str.toInt
  }

  implicit def strParser: ValParser[String] = new ValParser[String]{
    def parse(str:String):String = str
  }

  implicit def boolParser: ValParser[Boolean] = new ValParser[Boolean]{
    def parse(str:String):Boolean = str.toBoolean
  }

  implicit val hnilParser: FP[HNil] = create(HNil)

  private def findArg[K <: Symbol](implicit args:Args, named: Named[K]): String = {
    val name = named.value.name
    val index = args._2(name)
    args._1(index)
  }
}

请参阅.ts示例https://ng-bootstrap.github.io/#/components/modal/examples

你只需要这样做,现在你可以玩你的模态

编辑:要访问ng-template中的子组件://错误方式

open(engineModal) {
   console.log(this.engineModal) // global modal info from ViewChild
   console.log(engineModal) // modal info used for the function
   this.modalService.open(engineModal).result.then((result) => {
      this.closeResult = `Closed with: ${result}`;
   }, (reason) => {
   this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});

=&GT;我个人将ng-template封装在ModalInfoComponent,ModalNewsComponent html中并直接使用我的答案;)

答案 2 :(得分:0)

您可以通过将内容作为输入属性

进行投影来投影内容
<button class="btn btn-lg btn-outline-primary" (click)="open(element.innerHTML)">Launch demo modal</button>
<div #element style="display:none">>
  SOME THING PROJECTED
</div>

您的模态组件应具有以下modal-body

<div class="modal-body">
  <div [innerHTML]="modalBody">
  </div>
</div>

具有以下输入属性

@Input() modalBody:string;

更新1:要更改父级@Input()属性的值,可以按照以下方式进行,

setTimeout(()=>{
    this.modalRef.componentInstance.name = 'Opened After sometime';
},1000)

<强> LIVE DEMO