如何解决Angular 11 Universal 和 Bootstrap 5 Toast 不工作 - 新引导程序 TS2304:找不到名称“引导程序”,被压碎
我使用 Angular 11 Universal - 服务器端渲染。我正在尝试实现 Bootstrap 5 toast(css 效果很好),但它不理解类 new bootstrap:
angular.json - 正确导入
"styles": [
"src/styles.scss","node_modules/bootstrap/dist/css/bootstrap.min.css"
],"scripts": [
"node_modules/@popperjs/core/dist/umd/popper.min.js","node_modules/bootstrap/dist/js/bootstrap.min.js"
]
package.json
"@angular/platform-browser": "~11.2.7","@angular/platform-browser-dynamic": "~11.2.7","@angular/platform-server": "~11.2.7","@angular/router": "~11.2.7","@nguniversal/express-engine": "^11.2.1","@popperjs/core": "^2.9.2","bootstrap": "^5.0.0-beta3","express": "^4.15.2","popper.js": "^1.16.1",
我试图用最初的 JS 代码实现 toast:
import {
AfterViewInit,Component,ElementRef,EventEmitter,Inject,Input,OnInit,Output,PLATFORM_ID,ViewChild
} from '@angular/core';
import { Toast } from '../../../../../node_modules/bootstrap/dist/js/bootstrap.min.js'
import {isPlatformBrowser} from "@angular/common";
@Component({
selector: 'app-toast',templateUrl: './toast.component.html',styleUrls: ['./toast.component.scss']
})
export class ToastComponent implements OnInit,AfterViewInit {
@Output() closeHit: EventEmitter<boolean> = new EventEmitter<boolean>();
// @Input() title: string = "Toast";
@Input() message: string = 'Enter message here';
@ViewChild('toast') toast: ElementRef<HTMLDivElement>
constructor(@Inject(PLATFORM_ID) private platformId: Object) {
if (isPlatformBrowser(this.platformId)) {
// var toastElList = [].slice.call(document.querySelectorAll('.toast'))
// var toastList = toastElList.map(function (toastEl) {
return new bootstrap.Toast(this.toast,{})
// })
new Toast(this.toast);
// Array.from(document.querySelectorAll('.toast'))
// .forEach(toastNode => new Toast(toastNode))
}
}
ngOnInit(): void {
}
ngAfterViewInit() {
}
}
但它不理解类引导程序 - 在新引导程序 TS2304 中:找不到名称“引导程序”。
直接从 bootstrap.js 导入 toast 的 2 变体正在破坏应用程序 新吐司(this.toast);
ReferenceError: 文档未定义
发生服务器错误。
节点以 1 个代码退出。
连接 ECONNREFUSED 127.0.0.1:62043
npm 错误!代码生命周期
npm 错误!错误号 1
npm 错误!客户端@0.0.0 dev:ssr:ng run client:serve-ssr
npm 错误!退出状态 1
请帮忙!有没有办法在 Angular Universal 中使用 Bootstrap 5 功能进行吐司、模态?
解决方法
Angular 12 和 Bootstrap 5 .TS
@ViewChild('myToast',{static:true}) toastEl!: ElementRef<HTMLDivElement>;
toast: Toast | null = null;
ngOnInit()
{
this.toast = new Toast(this.toastEl.nativeElement,{});
}
show(){
this.toast!.show();
}
HTML
<button type="button" class="btn btn-primary" id="liveToastBtn"
(click)="show()">Show live toast</button>
<div #myToast role="alert" aria-live="assertive" aria-atomic="true"
class="toast fade" data-bs-autohide="false">
<div class="toast-header">
<img src="..." class="rounded me-2" alt="...">
<strong class="me-auto">Bootstrap</strong>
<small>11 mins ago</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-
label="Close"></button>
</div>
<div class="toast-body">
Hello,world! This is a toast message.
</div>
</div>
,
添加引导程序/类型
npm i @types/bootstrap
然后在你的组件中导入 Toast
import {Toast} from 'bootstrap'
为您的 Toast 使用模板参考
<div #myToast role="alert" aria-live="assertive" aria-atomic="true" class="toast fade" data-bs-autohide="false">
<div class="toast-header">
<img src="..." class="rounded me-2" alt="...">
<strong class="me-auto">Bootstrap</strong>
<small>11 mins ago</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
Hello,world! This is a toast message.
</div>
</div>
并使用带有静态 true 的 ViewChild 在 ngOnInit 中创建 Toast 元素
@ViewChild('myToast',{static:true}) toastEl: any
isClosed(){
return !this.toastEl.nativeElement.classList.contains('show')
}
toast:any
ngOnInit()
{
this.toast=new Toast(this.toastEl.nativeElement,{})
}
然后使用 toast.show() 或 toast.hide()
注意:您还可以使用具有 toast 组件的库,例如ng-bootstrap(我之所以这样说是因为更接近引导程序并且是“纯”Angular
更新我们可以使用指令改进代码
如果我们创建一个像
这样的指令import {Directive,ElementRef} from '@angular/core'
import {Toast} from 'bootstrap'
@Directive({
selector: '.toast',//<--(1)
})
export class ToastDirective {
toast:any;
isClosed(){
return !this.el.nativeElement.classList.contains('show')
}
constructor(private el:ElementRef){
this.toast=new Toast(this.el.nativeElement)
}
toogle()
{
if (this.isClosed())
this.toast.show();
else
this.toast.hide();
}
hide(){
this.toast.hide();
}
show(){
this.toast.show();
}
}
(1) 使指令应用于所有 class="toast" 的 div。
我们已经全部“封装”了,现在如果我们举杯
<div #myToast role="alert" aria-live="assertive" aria-atomic="true" class="toast fade" data-bs-autohide="false">
...
</div>
ViewChild 现在是
@ViewChild('myToast',{static:true,read:ToastDirective}) toast: ToastDirective
我们可以做到,例如
<button class="btn btn-primary" (click)="toast.toogle()">toogle</button>
我创建了 another stackblitz
,错误 npm ERR!在 client@0.0.0 dev:ssr 脚本失败 - 据我所知,它没有在服务器上呈现,引导程序需要 DOM,但这只是服务器端。
The app is crashed:
E:\PRACTICE\MYPETPROJECTS\tanechka\client\dist\client\server\main.js:79069
EventHandler.on(document,EVENT_CLICK_DATA_API$7,SELECTOR_DISMISS,Alert.handleDismiss(new Alert()));
^
ReferenceError: document is not defined
at E:\PRACTICE\MYPETPROJECTS\tanechka\client\dist\client\server\main.js:79069:19
at E:\PRACTICE\MYPETPROJECTS\tanechka\client\dist\client\server\main.js:78335:28
at Object.SYky (E:\PRACTICE\MYPETPROJECTS\tanechka\client\dist\client\server\main.js:78337:2)
at __webpack_require__ (E:\PRACTICE\MYPETPROJECTS\tanechka\client\dist\client\server\main.js:26:30)
at Module.Mvz9 (E:\PRACTICE\MYPETPROJECTS\tanechka\client\dist\client\server\main.js:71515:67)
at __webpack_require__ (E:\PRACTICE\MYPETPROJECTS\tanechka\client\dist\client\server\main.js:26:30)
at Module.PCNd (E:\PRACTICE\MYPETPROJECTS\tanechka\client\dist\client\server\main.js:74232:91)
at __webpack_require__ (E:\PRACTICE\MYPETPROJECTS\tanechka\client\dist\client\server\main.js:26:30)
at Module.ZAI4 (E:\PRACTICE\MYPETPROJECTS\tanechka\client\dist\client\server\main.js:90421:79)
at __webpack_require__ (E:\PRACTICE\MYPETPROJECTS\tanechka\client\dist\client\server\main.js:26:30)
A server error has occurred.
node exited with 1 code.
connect ECONNREFUSED 127.0.0.1:60499
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! client@0.0.0 dev:ssr: `ng run client:serve-ssr`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the client@0.0.0 dev:ssr script
对我来说,唯一正确的决定是拒绝在 Angular Universal 中使用 Bootstrap 并用 Angular Material SnackBar 和实用程序替换它。
https://material.angular.io/components/snack-bar/examples
这行代码
this.toast = new Toast(this.toastEl.nativeElement,{});
- 调用新的 Toast - 对于我尝试以任何方式实现它的方式,它在 Universal Angular 中不起作用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。