我试图找到一种在服务中拥有和管理angular2组件的方法,但没有成功:
我需要创建:
AlertService{
alertConfirm(msg): Promise;
}
alertConfirm将提示一个带有2个按钮的确认窗口(确定,取消)并返回用户'选择作为承诺。
该方法将返回一个Promise,其中包含用户选择的响应:" OK"或"取消"。
我试图找到一种方法来举办一个匿名的"组件,AlertComponent,在AlertService中:
AlertComponent{
showMsgConfirm(msg): Promise;
}
当用户关闭提示窗口或点击"确定&#34>时,Promise将设置响应。或"取消"。
如何制作" AlertService"有一个内部" AlertComponent"这可以由它管理" alertOK"方法
我的意思是,我没有为" alertConfirm"找到方法。打电话给#34; showMsgConfirm"方法并将其作为回应返回。
例如,从主应用程序组件调用:
this.alertService.alertConfirm("Save changes?").then(res => {
if(res.ok){console.log("Can be saved");
}, err=> { });
对此有何想法?
谢谢,
更新:2个不同的解决方案,但没有成功管理AlertComponent:
import { Injectable, ViewContainerRef, ReflectiveInjector, ComponentFactoryResolver, ComponentRef } from '@angular/core';
import { AlertComponent } from './../components/modales/AlertComponent/AlertComponent.component';
@Injectable()
export class AlertService {
constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
public createAlertComp(vCref: ViewContainerRef): ComponentRef<any> {
let factory = this.componentFactoryResolver.resolveComponentFactory(AlertComponent);
/*
//Option 1:
// vCref is needed cause of that injector..
let injector = ReflectiveInjector.fromResolvedProviders([], vCref.parentInjector);
// create component without adding it directly to the DOM
let comp = factory.create(injector);
// add inputs first !! otherwise component/template crashes ..
comp.instance.model = modelInput;
// all inputs set? add it to the DOM ..
vCref.insert(comp.hostView);
return comp;
*/
//Option 2:
var componentRef: ComponentRef<AlertComponent> = vCref.createComponent(factory);
return null;
}
}
答案 0 :(得分:0)
答案是......:
服务:
import { Injectable, ViewContainerRef, ReflectiveInjector, ComponentFactoryResolver, ComponentRef, EventEmitter } from '@angular/core';
import { CtmAlertComponent } from './ctmAlert/ctmAlert.component';
@Injectable()
export class AlertCtmService {
private _vcr: ViewContainerRef;
private _counter: number = 0;
constructor(private componentFactoryResolver: ComponentFactoryResolver, public viewRef: ViewContainerRef) {
console.log("AlertCtmService.constructor:");
//TODO: Consider appending to this.viewRef: "#alertCtmServiceContainer" as a Dom elemnt perent container which will hold all AlertModals:
// Maybe by:
// this.viewRef.element.nativeElement.insertAdjacentHTML('beforeend', '<div class="alertCtmServiceContainer"></div>');
this._vcr = this.viewRef;
}
public alertOK(alertMsg: string): EventEmitter<any> {
return this.createEventEmitterComponent("CtmAlertComponent", alertMsg, false);
}
public alertConfirm(alertMsg: string): EventEmitter<any> {
return this.createEventEmitterComponent("CtmAlertComponent", alertMsg, true);
}
private createEventEmitterComponent(componentName: string, alertMsg: string, isConfirm: boolean): EventEmitter<any> {
console.log("AlertCtmService.createEventEmitterComponent:");
switch (componentName) {
case "CtmAlertComponent":
default:
var _component = CtmAlertComponent;
break;
}
let factory = this.componentFactoryResolver.resolveComponentFactory(_component);
// vCref is needed cause of that injector..
let injector = ReflectiveInjector.fromResolvedProviders([], this._vcr.parentInjector);
// create component without adding it directly to the DOM
let comp = factory.create(injector);
// add inputs first !! otherwise component/template crashes ..
comp.instance.close.subscribe(resp => {
console.log("AlertCtmService.createEventEmitterComponent: comp.instance.close.subscribe: resp=" + resp.ok);
comp.destroy();
})
comp.instance.alertBodyMsg = alertMsg;
comp.instance.isConfirm = isConfirm;
comp.instance.nameId = "Modal" +(++this._counter).toString();
// all inputs set? add it to the DOM ..
this._vcr.insert(comp.hostView);
//return null;
return comp.instance.close;
}
public init(vCref: ViewContainerRef): ViewContainerRef {
this._vcr = vCref;
return this._vcr;
}
}
import { Component, AfterViewInit, Input, ViewChild, ElementRef, Renderer, NgZone, EventEmitter} from '@angular/core';
@Component({
selector: 'ctm-alert',
styles: [``],
templateUrl: '/app/shared/alertCtm/ctmAlert/CtmAlert.component.html',
styleUrls: ['./app/shared/alertCtm/ctmAlert/CtmAlert.component.css'],
providers: []
})
export class CtmAlertComponent implements AfterViewInit {
public ModalIsVisible: boolean;
//private static subscriptions: Object = {};
//enums = Enums;
close = new EventEmitter();
public nameId = "";
private isOk = false;
alertBodyMsg: string = "";
isConfirm = false;
constructor() {
console.log("CtmAlertComponent.constructor:");
}
ngAfterViewInit() {
this.showModal();
var attrId = this.getIdAttr();
$('#' + attrId).on('hidden.bs.modal', function () {
debugger;
console.log('CtmAlertComponent: #licenseModal_XXX.on(hidden.bs.modal)');
this.submitStatus();
}.bind(this) );
}
showModal() {
this.ModalIsVisible = true;
var attrId = '#' +this.getIdAttr();
$(attrId).modal('show');
}
hideModal() {
this.ModalIsVisible = false;
var attrId = '#' + this.getIdAttr();
$(attrId).modal('hide');
}
getIdAttr(): string {
return "ctmAlertModal_" + this.nameId;
}
submitStatus() {
var resp = { ok: (this.isOk == true) };
this.close.emit(resp);
}
submitOk() {
this.isOk = true;
this.hideModal();
}
submitCancel() {
this.isOk = false;
this.hideModal();
}
}
应用宣言:
entryComponents
的声明:[CtmAlertComponent],
import { CtmAlertComponent } from './shared/alertCtm/ctmAlert/ctmAlert.component';
@NgModule({
imports: [
BrowserModule,
HttpModule,
AppRoutingModule,
...
],
declarations: [
CtmAlertComponent,
AppComponent,
...
],
entryComponents: [CtmAlertComponent],
providers: [
...
],
bootstrap: [AppComponent],
})
export class AppModule { }
enableProdMode();
模态用户界面:
<div class="ctmAlertModal modal fade in" [id]="getIdAttr()" role="dialog">
<div class="modal-dialog modal-lg" [ngClass]="{'modal-lg-6': true }">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header" style="">
<div class="pull-right" style="position: relative;">
<a href="#" data-dismiss="modal" (click)="hideModal()"><span class="fa fa-times-circle" aria-hidden="true" style="color: #949494"></span></a>
</div>
</div>
<div class="modal-body">
<div class="modal-body-msg">
{{alertBodyMsg}}
</div>
<div class="modal-body-buttons">
<div style="margin: 0 auto;" [style.width]="(isConfirm)? '165px' : '70px' ">
<button type="button" *ngIf="isConfirm" class="btn-submit pull-left btn-cancel" [ngClass]="{'disabled': false }" [disabled]="false" (click)="submitCancel()">
<!--<img alt="End-Training" class="centering-me2" src="../../../contents/training_state_stop_white.svg">-->
Cancel
</button>
<button type="button" class="btn-submit pull-right" [ngClass]="{'disabled': false }" [disabled]="false" (click)="submitOk()">
<!--<img alt="Resume-Training" src="../../../contents/training_state_play_white.svg">-->
OK
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<强>用法:强>:
this.alertCtmService.alertOK("Save changes???").subscribe(function (resp) {
console.log("alertCtmService.alertOK.subscribe: resp=" + resp.ok);
this.saveData();
}.bind(this) );
**
**
来源: