Struggling to transfer an object from ng-bootstrap modal to main(view) component using the @Output
decorator.
This is my HTML(viewProducts.component.html), where a list of products are shown, when I click on one of them, the modal is invoked:
<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;
}
}
And finally, the HTML modal form where I edit the product data(editProduct.component.html). When I click on the save button into editProduct.component.ts (work with a copy of the product - to avoid the two-way data binding) and try to push back modified product data into the 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);
}
}
}
I do not know how to push back modified data into editProduct.component.html. Any suggestions?
答案 0 :(得分:1)
You have to use a service. Here is an example:
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);
}
}
In your ViewProductsComponent subscribe to this StorageService and have your local variable that provides updated product exchanged whenever the value inside the service changes.
import {StorageService} from 'storage.service.ts';
constructor(
private storageService: StorageService
){}
ngOnInit(): void {
// Update with every change
this.storageService.getProduct().subscribe(product => {
this.modifiedProduct = product;
});
}
And your Modal has to set the value to the StorageSevice instead of emitting it
import {StorageService} from 'storage.service.ts';
constructor(
private storageService: StorageService
){}
save() {
this.service.updateProduct(this.productCopy).subscribe((res) => {
this.storageService.setProduct(res);
}
}