简体   繁体   English

Angular 11 Universal 和 Bootstrap 5 Toast 不工作 - 新引导 TS2304:找不到名称“bootstrap”,已损坏

[英]Angular 11 Universal and Bootstrap 5 Toast not working- new bootstrap TS2304: Cannot find name 'bootstrap', crushed

I work with Angular 11 Universal - server side rendering.我使用 Angular 11 Universal - 服务器端渲染。 I'm trying to implement Bootstrap 5 toasts (css works well), but it doesn't understand class new bootstrap:我正在尝试实现 Bootstrap 5 toasts(css 运行良好),但它不理解 class 新的引导程序: 在此处输入图像描述

angular.json - it's imported properly 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 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",

I was trying to implement toasts with initial JS code:我试图用初始 JS 代码实现 toasts:

 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() { } }

But it don't understand class bootstrap - in new bootstrap TS2304: Cannot find name 'bootstrap'.但它不理解 class bootstrap - 在新的 bootstrap TS2304 中:找不到名称“bootstrap”。

2 variant with importing toast directly from bootstrap.js is breaking the app new Toast(this.toast); 2 直接从 bootstrap.js 导入 toast 的变体破坏了应用程序 new Toast(this.toast);

ReferenceError: document is not defined A server error has occurred. ReferenceError: document is not defined 发生服务器错误。 node exited with 1 code.节点以 1 个代码退出。 connect ECONNREFUSED 127.0.0.1:62043 npm ERR.连接 ECONNREFUSED 127.0.0.1:62043 npm 错误。 code ELIFECYCLE npm ERR.代码 ELIFECYCLE npm 错误。 errno 1 npm ERR: client@0:0.0 dev:ssr: ng run client:serve-ssr npm ERR! errno 1 npm ERR: client@0:0.0 dev:ssr: ng run client:serve-ssr npm ERR! Exit status 1退出状态 1

Please, help, Is there any way to use Bootstrap 5 functionality for toasts?求助,有什么方法可以使用 Bootstrap 5 功能进行吐司吗? modals in Angular Universal? Angular 通用模态?

Angular 12 & Bootstrap 5.TS Angular 12 & 引导程序 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 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>

Add the bootstrap/Types添加引导程序/类型

npm i @types/bootstrap

Then in your component import Toast然后在你的组件中导入 Toast

import {Toast} from 'bootstrap'

Use a template reference for your 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>

And use ViewChild with static true to create the Toast element in ngOnInit并使用 ViewChild 和 static true 在 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,{})
  }

Then use toast.show() or toast.hide()然后使用 toast.show() 或 toast.hide()

see the stackblitz堆栈闪电战

NOTE: You can also use librarys that has toast component, eg ng-bootstrap (I put this because is closer to bootstrap and is "pure" Angular注意:您还可以使用具有 toast 组件的库,例如ng-bootstrap (我之所以这样说是因为它更接近引导程序并且是“纯”Angular

Update We can improve the code using a directive更新我们可以使用指令改进代码

If we create a directive like如果我们创建一个类似的指令

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) make that the directive is applied to all the div with class="toast". (1) 使该指令适用于所有具有 class="toast" 的 div。

We has all "encapsulated", now if we has a toast我们都“封装”了,现在如果我们举杯

<div #myToast role="alert" aria-live="assertive" aria-atomic="true" class="toast fade" data-bs-autohide="false">
...
</div>

ViewChild is now ViewChild 现在是

 @ViewChild('myToast',{static:true,read:ToastDirective}) toast: ToastDirective

And we can do, eg我们可以做,例如

<button class="btn btn-primary" (click)="toast.toogle()">toogle</button>

I create another stackblitz我创建了另一个堆栈闪电战

npm install bootstrap
npm install @types/bootstrap


code...
const Bootstrap = await import('bootstrap');
const Modal = new Bootstrap.Modal(...element..., ...options...);

angular.json
"build": {
    ...,
    "options": {
        ...,    
        "allowedCommonJsDependencies": [
            "bootstrap"
        ],
        ...
    },
    ...
}

Toast try like this像这样吐司

Error npm ERR.错误 npm ERR。 Failed at the client@0.0:0 dev,ssr script - it's not rendering on server as I understand, bootstrap needs DOM.在 client@0.0:0 dev,ssr 脚本上失败 - 据我了解,它没有在服务器上呈现,引导程序需要 DOM。 but this is just server side.但这只是服务器端。

 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

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

Single right decision for me was to refuse from using Bootstrap in Angular Universal and replacing it with Angular Material SnackBar and utilities.对我来说,唯一正确的决定是拒绝在 Angular Universal 中使用 Bootstrap,并将其替换为 Angular Material SnackBar 和实用程序。

https://material.angular.io/components/snack-bar/examples https://material.angular.io/components/snack-bar/examples

This line of code这行代码

 this.toast = new Toast(this.toastEl.nativeElement,{});

  • calling new Toast - it didn't work in Universal Angular for how I was trying to implement it in any ways.调用 new Toast - 它在 Universal Angular 中不起作用,因为我试图以任何方式实现它。

You can also try the following npm package for snackbar.您也可以尝试以下 npm package 用于小吃吧。 This package is having default theme as bootstrap with the Angular Material Implementation.这个 package 使用 Angular 材料实现作为引导程序的默认主题。

npm install --save @tech-pro/ngx-bootstrap-snackbar

NPM Link To Package NPM 链接到 Package

Demo演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 错误TS2304:将ng-bootstrap添加到Angular2的TypeScript快速入门时,找不到名称&#39;NGB_PRECOMPILE&#39; - error TS2304: Cannot find name 'NGB_PRECOMPILE' when adding ng-bootstrap to Angular2 quick start for TypeScript @ ng-bootstrap / ng-bootstrap / pagination / pagination.d.ts(52,14):错误TS2304:找不到名称“ pageCount” - @ng-bootstrap/ng-bootstrap/pagination/pagination.d.ts (52,14): error TS2304: Cannot find name 'pageCount' Fullcalendar + Angular 6 和 jQuery:TS2304:找不到名称“JQueryPromise” - Fullcalendar + Angular 6 and jQuery: TS2304: Cannot find name 'JQueryPromise' 错误TS2304:在Angular 5中找不到名称&#39;trim&#39; - error TS2304: Cannot find name 'trim' in Angular 5 @角度/常见错误TS2304找不到名称“未知” - @angular/common error TS2304 cannot find name 'unknown' 角度错误TS2304:找不到名称'config' - Angular error TS2304: Cannot find name 'config' TS2304:在Webpack / Angular 2中找不到名称“描述” - TS2304: Cannot find name 'describe' in Webpack / Angular 2 错误 TS2304:找不到名称“HeatmapOverlay”+ 角度 10 - error TS2304: Cannot find name 'HeatmapOverlay' + angular 10 Angular(6) 的错误 TS2304:找不到名称“ICurrentWeatherData” - Angular(6)'s Error TS2304: Cannot find name 'ICurrentWeatherData' TS2304:找不到名称 - TS2304: Cannot find name
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM