如何将对象从 ng-bootstrap 模式推回到 Angular 中的主要组件?

How to push back an object from ng-bootstrap modal to main component in Angular?

努力使用 @Output 装饰器将对象从 ng-bootstrap 模态传输到主(视图)组件。 这是我的 HTML(viewProducts.component.html),其中显示了产品列表,当我单击其中一个时,将调用模式:

<tr *ngFor="let product of products>
    <td class="text-center">
        <button class="btn btn-default" name="openPopUp" 
          (click)="openPopUpEdit(product)" 
          (callBackPopUp)="callBackPopUp($event)">
          <i class="fa fa-edit" style="font-size: 20px"></i>
        </button>
    </td>
</tr>

viewProducts.component.ts

 openPopUpEdit(product) {
   this.editProductModalService.open(EditProductComponent as Component, 
    product);
}

editProduct-modal.service.ts

@Injectable()
export class EditProductModalService {
    private ngbModalRef: NgbModalRef;
    constructor(
        private modalService: NgbModal
    ) {
        this.ngbModalRef = null;
    }

    open(component: Component,  product: ProductModel): Promise<NgbModalRef> {
        return new Promise<NgbModalRef>((resolve, reject) => {
            const isOpen = this.ngbModalRef !== null;
            if (isOpen) {
                resolve(this.ngbModalRef);
            }
            setTimeout(() => {
                this.ngbModalRef = this.manageModalRef(component, product);
                resolve(this.ngbModalRef);
            }, 0);
        });
    }

    manageModalRef(component: Component, product: ProductModel): NgbModalRef {
        const modalRef = this.modalService.open(component, { size: 'lg', backdrop: 'static' });
        (<EditProductComponent> modalRef.componentInstance).product = product;
        modalRef.componentInstance.callBackPopUp.subscribe(($e) => {
            console.log('call back:' + $e);
        })
        modalRef.result.then((result) => {
            this.ngbModalRef = null;
        }, (reason) => {
            console.log('dismiss reason: ' + reason);
            this.ngbModalRef = null;
        });
        return modalRef;
    }
}

最后,我编辑产品数据的 HTML 模态表单 (editProduct.component.html)。当我单击保存按钮进入 editProduct.component.ts(使用产品的副本 - 避免双向数据绑定)并尝试将修改后的产品数据推回 viewProducts.component.html :

@Component({
    selector: 'editProduct',
    templateUrl: './editProduct.component.html'
})
export class EditProductComponent implements OnInit, OnDestroy {
    @Input() product: ProductModel;
    @Output() callBackPopUp: EventEmitter<ProductModel> = new 
    EventEmitter<ProductModel>();
    productCopy: ProductModel;   

    constructor(
        private activeModal: NgbActiveModal,       
        private service: ProductService,
     ) { }

    ngOnInit() {
        this.productCopy = Object.assign({}, this.product);       
    }

    save() {  
        this.service.updateProduct(this.productCopy).subscribe((res) => {
            this.callBackPopUp.emit(this.productCopy);                    
        }   
    }
}

我不知道如何将修改后的数据推回 editProduct.component.html。有什么建议吗?

您必须使用一项服务。这是一个例子:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';


@Injectable()
export class StorageService {

    private product: BehaviorSubject<ProductModel> = new BehaviorSubject('');

    constructor() { }

    getProduct(): Observable<ProductModel> {
        return this.product.asObservable();
    }

    getProductValue(): ProductModel {
        return this.product.getValue();
    }

    setProduct(val: ProductModel) {
        this.product.next(val);
    }
}

在您的 ViewProductsComponent 中订阅此 StorageService 并让您的本地变量在服务中的值发生变化时提供更新的产品。

import {StorageService} from 'storage.service.ts';

constructor(
 private storageService: StorageService
){}

ngOnInit(): void {
    // Update with every change
    this.storageService.getProduct().subscribe(product => {
        this.modifiedProduct = product; 
    });
}

并且您的 Modal 必须将值设置为 StorageSevice 而不是发出它

import {StorageService} from 'storage.service.ts';

constructor(
 private storageService: StorageService
){}

save() {  
    this.service.updateProduct(this.productCopy).subscribe((res) => {
        this.storageService.setProduct(res);                    
    }   
}