我试图在Angular 2中使用一个简单的Modal,我可以在任何页面中使用它而不需要添加HTML标记,因为我想保持我的.htmls干净。我正在考虑像Angular JS中的bootstrap一样的Modal,但我找不到那样的东西。 我尝试使用ngx-modialog,但我遇到以下错误:
MatchesComponent.html:37 ERROR TypeError: __WEBPACK_IMPORTED_MODULE_0__angular_core__.E.create is not a function
at DOMOverlayRenderer.webpackJsonp.../../../../ngx-modialog/bundle/ngx-modialog.es5.js.DOMOverlayRenderer.render (http://localhost:4200/vendor.bundle.js:59597:87)
at Overlay.webpackJsonp.../../../../ngx-modialog/bundle/ngx-modialog.es5.js.Overlay.createOverlay (http://localhost:4200/vendor.bundle.js:59555:48)
at http://localhost:4200/vendor.bundle.js:59537:47
at Array.map (native)
at Overlay.webpackJsonp.../../../../ngx-modialog/bundle/ngx-modialog.es5.js.Overlay.open (http://localhost:4200/vendor.bundle.js:59537:14)
at Modal$$1.webpackJsonp.../../../../ngx-modialog/bundle/ngx-modialog.es5.js.Modal.open (http://localhost:4200/vendor.bundle.js:59670:53)
at OneButtonPresetBuilder.webpackJsonp.../../../../ngx-modialog/bundle/ngx-modialog.es5.js.ModalOpenContextBuilder.open (http://localhost:4200/vendor.bundle.js:60002:30)
at MatchesComponent.webpackJsonp.../../../../../src/app/components/matches/matches.component.ts.MatchesComponent.viewItemInfo (http://localhost:4200/main.bundle.js:801:14)
at Object.eval [as handleEvent] (ng:///AppModule/MatchesComponent.ngfactory.js:61:27)
app.module
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HttpModule } from '@angular/http';
import { FormsModule } from '@angular/forms';
import { ModalModule } from 'ngx-modialog';
import { BootstrapModalModule } from 'ngx-modialog/plugins/bootstrap';
import { AppComponent } from './app.component';
import { LoginComponent } from './components/login/login.component';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { AlertsComponent } from './components/alerts/alerts.component';
import { MatchesComponent } from './components/matches/matches.component';
import { ProductsComponent } from './components/products/products.component';
import { ShipmentsComponent } from './components/shipments/shipments.component';
import { ComplaintsComponent } from './components/complaints/complaints.component';
import { UsersComponent} from './components/users/users.component';
import { StatisticsComponent } from './components/statistics/statistics.component';
import { BillingComponent } from './components/billing/billing.component';
import { NotificationsComponent } from './components/notifications/notifications.component';
import { PagenotfoundComponent } from './components/pagenotfound/pagenotfound.component';
import { AuthService } from './services/auth.service';
const appRoutes: Routes = [
{ path: '', redirectTo: '/login', pathMatch: 'full'},
{ path: 'login', component: LoginComponent },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'alerts', component: AlertsComponent, canActivate: [AuthService] },
{ path: 'matches', component: MatchesComponent, canActivate: [AuthService] },
{ path: 'products', component: ProductsComponent, canActivate: [AuthService] },
{ path: 'shipments', component: ShipmentsComponent, canActivate: [AuthService] },
{ path: 'complaints', component: ComplaintsComponent, canActivate: [AuthService] },
{ path: 'users', component: UsersComponent, canActivate: [AuthService] },
{ path: 'statistics', component: StatisticsComponent, canActivate: [AuthService] },
{ path: 'billing', component: BillingComponent, canActivate: [AuthService] },
{ path: 'notifications', component: NotificationsComponent, canActivate: [AuthService] },
{ path: '**', component: PagenotfoundComponent }
];
@NgModule({
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
AlertsComponent,
MatchesComponent,
ProductsComponent,
ShipmentsComponent,
ComplaintsComponent,
UsersComponent,
StatisticsComponent,
BillingComponent,
NotificationsComponent,
PagenotfoundComponent,
],
imports: [
BrowserModule,
HttpModule,
FormsModule,
ModalModule,
BootstrapModalModule,
RouterModule.forRoot(
appRoutes,
)
],
providers: [
AuthService,
],
bootstrap: [AppComponent]
})
export class AppModule { }
matches.component.ts
import { Component } from '@angular/core';
import { ApiService } from '../../services/api.service';
import { AuthService } from '../../services/auth.service';
import { TableComponent } from '../alerts/alerts.component';
import { Modal } from 'ngx-modialog/plugins/bootstrap';
import * as _ from 'lodash';
export class ItemsResult {
data: [Object];
total: number;
}
@Component({
selector: 'app-matches',
templateUrl: './matches.component.html',
styleUrls: ['./matches.component.less'],
providers: [ ApiService , AuthService ]
})
export class MatchesComponent {
tableHeaders: TableComponent[] = [
{ name: 'ID', attribute: '_id' },
{ name: 'Fecha de Expiración', attribute: 'expire_at' },
{ name: 'Item ID', attribute: 'item_id' },
{ name: 'Nombre Item', attribute: 'item_title'},
{ name: 'Order ID', attribute: 'order_id' },
{ name: 'Nombre Order', attribute: 'order_title' },
{ name: 'Stock', attribute: 'stock' },
{ name: 'Ver Order', attribute: '' }
];
filterOptions: TableComponent[] = [
{ name: 'ID', attribute: '_id' },
{ name: 'Item ID', attribute: 'item_id' },
{ name: 'Nombre Item', attribute: 'item_title' },
{ name: 'Order ID', attribute: 'order_id' },
{ name: 'Nombre Order', attribute: 'order_title' }
];
actualPage = 0;
filteredList;
total;
sorted = false;
filterType = this.filterOptions[0].attribute;
filterValue = '';
constructor( public apiService: ApiService, public auth: AuthService, public modal: Modal ) {
this.updateMatches();
}
updateMatches(): void {
this.apiService.getMatchesForPage(this.actualPage, '', this.filterType, this.filterValue).then((result: ItemsResult) => {
console.log(result);
this.total = result.total;
this.filteredList = result.data;
});
}
changePageUp(): void {
const limit = this.total / 100;
if (this.actualPage < limit) {
this.actualPage++;
}
this.updateMatches();
}
changePageDown(): void {
if (this.actualPage > 0) {
this.actualPage--;
}
this.updateMatches();
}
sortBy(attribute: string): void {
if (this.sorted) {
this.filteredList = _.orderBy(this.filteredList, [attribute], ['asc']);
} else {
this.filteredList = _.orderBy(this.filteredList, [attribute], ['desc']);
}
this.sorted = !this.sorted;
}
viewItemInfo(itemId): void {
this.modal.alert()
.size('lg')
.showClose(true)
.title('A simple Alert style modal window')
.body(`
<h4>Alert is a classic (title/body/footer) 1 button modal window that
does not block.</h4>
<b>Configuration:</b>
<ul>
<li>Non blocking (click anywhere outside to dismiss)</li>
<li>Size large</li>
<li>Dismissed with default keyboard key (ESC)</li>
<li>Close wth button click</li>
<li>HTML content</li>
</ul>`)
.open();
}
viewOrderInfo(orderId): void {
}
}
我猜这个错误不是因为模态模块,但是我错过了一些依赖,但我无法弄清楚哪一个,任何帮助都非常感激。
此致
答案 0 :(得分:0)
在app.module中,尝试在导入ModalModule时调用.forRoot(): (根据ngx-modialog quickstart docs)
imports: [
BrowserModule,
HttpModule,
FormsModule,
ModalModule.forRoot(), //instead of just ModalModule
BootstrapModalModule,
RouterModule.forRoot(
appRoutes,
)
],
答案 1 :(得分:0)
今天我犯了同样的错误。我试图用组件实现自定义模态窗口。我用ngx-modialog试了一下,出现了错误。用旧版本(angular2-modal 3.0.2而不是ngx-modialog)和typescript版本2.3.4测试后,错误消失了。
答案 2 :(得分:0)
在与Modals A LOT挣扎之后,我终于决定制作我自己的模态,我认为比我在那里发现的模式要好得多,因为它接收参数并且可以在其体内包含任何HTML,我将它保留在这里有这个问题的人要用它。重新诠释如下:
不要忘记在样式中包含bootstrap.min.css,在脚本中包含jquery.min.js。
完成此操作后,您应该在app.module.ts中包含bootstrap:
...
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
...
imports: [
...
NgbModule.forRoot(),
...
]
...
然后你可以使用我创建的组件:
import { Component } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { isUndefined } from 'util';
@Component({
selector: 'app-custom-modal',
template: `
<div class="modal-header">
<h4 class="modal-title">{{title}}</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" [innerHTML]="bodyHTML">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="successFunction()">{{okButtonText}}</button>
<button type="button" class="btn btn-outline-dark" (click)="cancelFunction()">{{cancelButtonText}}</button>
</div>
`,
styleUrls: ['./custom-modal.component.less']
})
export class CustomModalComponent {
title;
bodyHTML;
okButtonText = 'Aceptar';
cancelButtonText = 'Cerrar';
successCallback;
cancelCallback;
constructor(public activeModal: NgbActiveModal) {}
successFunction() {
this.activeModal.close('Close click');
if (!isUndefined(this.successCallback)) {
this.successCallback();
}
}
cancelFunction() {
this.activeModal.close('Close click');
if (!isUndefined(this.cancelCallback)) {
this.cancelCallback();
}
}
}
用法示例:
...
constructor( private modalService: NgbModal ) {}
...
sendNotification() {
//send notification...
const modalRef = this.modalService.open(CustomModalComponent);
modalRef.componentInstance.title = 'Notification Sent';
modalRef.componentInstance.bodyHTML = '<p>Notification Succesfully sent.</p>';
}
这个模式是由我制作的,它的工作原理和完全可定制的,随意根据需要进行更改。希望它可以帮助别人!
此致