ngx-bootstrap + Angular 12 Открытие модала из другого компонента

Во-первых, я не русский, но я пользуюсь переводчиком.

Я пытаюсь создать общий модальный компонент ngx-bootstrap в Angular.

Я искал в Интернете и пробовал этот способ.

import { Component } from '@angular/core';
import { BsModalService } from 'ngx-bootstrap/modal';
import { BsModalRef } from 'ngx-bootstrap/modal/modal-options.class';

/* This is the Component from which we open the Modal Component */
@Component({
  selector: 'my-component',
  templateUrl: './service-component.html'
})
export class MyComponent {
  bsModalRef: BsModalRef;
  constructor(private modalService: BsModalService) {}

  public openModalWithComponent() {
    /* this is how we open a Modal Component from another component */
    this.bsModalRef = this.modalService.show(ModalContentComponent);
  }
}

/* This is the Modal Component */
@Component({
  selector: 'child-modal',
  template: `
    <div class="modal-header">
      <h4 class="modal-title pull-left">Title</h4>
      <button type="button" class="close pull-right" aria-label="Close" (click)="bsModalRef.hide()">
        <span aria-hidden="true">&times;</span>
      </button>
    </div>
    <div class="modal-body">
      ...
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-default" (click)="bsModalRef.hide()">Close</button>
    </div>
  `
})
export class ChildModalComponent {
  constructor(public bsModalRef: BsModalRef) {}
}

<button type="button" class="btn btn-primary" (click)="openModalWithComponent()">Create modal with component</button>

<child-modal #childModal ></child-modal>

Но для меня это 'Cannot find name 'ModalContentComponent'

И я действительно не понимаю, откуда они это берут, хотя для других людей это, похоже, работает.


Ответы (1 шт):

Автор решения: ivanao

Наконец, я последовал этому другому руководству, которое помогло мне. Внешняя ссылка.

Следующий пример используется для добавления элементов в массив:

Создайте простой компонент ItemList для отображения списка элементов, добавленных в массив.

ng g c itemList

item-list.component.html

<div>
    <h1> Item List </h1>
    <ul>
    <li *ngFor=”let item of itemList”>{{item}}</li>
    </ul>
    <button type=”button” class=”btn btn-primary”>Add New Item</button>
</div>

item-list.component.ts

export class ItemListComponent implements OnInit {
  itemList = ["Book","Pen"]
  constructor() { }
  ngOnInit() {
  }
}

Давайте создадим еще один компонент, который будет использоваться в качестве модального.

ng g c itemAdd

Второй компонент для добавления нового элемента, который в будущем будет использоваться как модальный. Также я написал простую функцию saveToList(), которая также будет реализована в будущем. На данный момент я поместил простой консольный журнал, просто для отображения значения в поле ввода.

NumberOfItems - это количество элементов в существующем массиве.

item-add.component.html

<div class="modal-body">
    <h4>Add Item</h4>
    <form [formGroup]="itemform" (ngSubmit)="saveToList(itemform)">
        <div class="col-md-6">
            <label>Number of Items : </label> {{numberOfItems}}
        </div>
        <div class="col-md-6">
            <label>Item Name</label>
        </div>
        <div class="col-md-6">
            <input type="text" class="form-control" formControlName="name">
            <button class="button mt-1" type="submit">Save</button>
        </div>
    </form>
<div>

item-add.component.ts

export class ItemAddComponent implements OnInit {
     itemform;
     numberOfItems = 0;
     constructor(private formBuilder: FormBuilder) {
         this.itemform = this.formBuilder.group({
         name: ""
         })
     }

     ngOnInit() {
     }

     saveToList(form) {
        console.log(form.value);
     }
}

Добавьте модальное окно.
Давайте изменим код, чтобы при нажатии на кнопку Add New Item форма добавления элемента открывалась как модальная.

item-list.component.ts

export class ItemListComponent implements OnInit {
 itemList = ["Book","Pen"];
 bsModalRef: BsModalRef;
 constructor(private modalService: BsModalService) { }
 
 ngOnInit() {
 }
 
 openModalWithComponent() {
   this.bsModalRef = this.modalService.show(ItemAddComponent);
   this.bsModalRef.content.closeBtnName = 'Close'; 
 }
}

Не забудьте добавить ItemAddComponent в список entryComponents в app.module.ts

providers: [],
entryComponents: [ItemAddComponent],

Передача значений от родителя к модалу.
Мы можем просто использовать initialState для передачи начального значения в модал.

item-list.component.ts

openModalWithComponent() {
    const initialState = {
        list: [
            "test"
        ]
    };
    this.bsModalRef = this.modalService.show(ItemAddComponent, {initialState});
    this.bsModalRef.content.closeBtnName = 'Close'; 
}

Чтобы прочитать это значение из модала добавления элемента.
Инициализация списка внутри модала, item-add.component.ts

list: any[] = [];

Then the initialState list can access as “list[]”.
We are sending a sample data “test” and it can be accessed as list[0] from item-add.component.html

<label>Number of Items : </label> {{list[0]}}

Подумайте, что мы хотим передать объект из списка элементов в модал.

item-list.component.ts

openModalWithComponent() {
  const initialState = {
    list: [
      {"tag":'Count',"value":this.itemList.length}
    ]
  };
  this.bsModalRef = this.modalService.show(ItemAddComponent, {initialState});
  this.bsModalRef.content.closeBtnName = 'Close'; 
}

--

<label>Number of Items : </label> {{list[0].value}}

Передача значений из модальной формы в дочернюю.
Давайте посмотрим, как передать значение в список элементов из формы добавления элемента. Объявите EventEmitter внутри item-add.component.ts

public event: EventEmitter<any> = new EventEmitter();

Выдача события при сохранении элемента.

triggerEvent(item: string) {
    this.event.emit({ data: item , res:200 });
}

item-add.component.ts

export class ItemAddComponent implements OnInit {
  itemform;
  numberOfItems = 0;
  list: any[] = [];
  public event: EventEmitter<any> = new EventEmitter();
  constructor(private formBuilder: FormBuilder, public bsModalRef: BsModalRef) {}

  ngOnInit() {
    this.itemform = this.formBuilder.group({
      name: ""
    })
  }

  saveToList(form) {
    this.triggerEvent(form.value.name);
    this.bsModalRef.hide();
  }

  triggerEvent(item: string) {
    this.event.emit({ data: item , res:200 });
  }
}

А внутри item-list.component.ts мы можем подписаться на event emitter.

item-list.component.ts

openModalWithComponent() {
  const initialState = {
    list: [
      {"tag":'Count',"value":this.itemList.length}
    ]
  };
  this.bsModalRef = this.modalService.show(ItemAddComponent, {initialState});
  this.bsModalRef.content.closeBtnName = 'Close';

  this.bsModalRef.content.event.subscribe(res => {
    this.itemList.push(res.data);
  });
}

Извините за мой русский, я пользуюсь переводчиком.

→ Ссылка