问题
I'm new to Bootstrap and trying to activate the .collapse() function from Javascript in an Angular controller when a user clicks on a link. This should close the collapsible navbar when one of the links is clicked (because the routing is controlled by Angular and doesn't cause a page refresh).
The following error shows:
ERROR TypeError: $(...).collapse is not a function
at HTMLAnchorElement.<anonymous> (header.component.ts:18)
at HTMLAnchorElement.dispatch (jquery.js:5183)
at HTMLAnchorElement.elemData.handle (jquery.js:4991)
at ZoneDelegate.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Object.onInvokeTask (core.js:4740)
at ZoneDelegate.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
at Zone.webpackJsonp../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
at ZoneTask.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:496)
at invokeTask (zone.js:1540)
at HTMLAnchorElement.globalZoneAwareCallback (zone.js:1577)
Relevant part of HTML template:
<div class='collapse navbar-collapse' id='mainNavbar'>
<div class='navbar-nav'>
<div [ngClass]='{ "nav-item": true, active: pageTitle === "Home" }'>
<a class='nav-link' routerLink='/'>Home</a>
</div>
<div [ngClass]='{ "nav-item": true, active: pageTitle === "Request" }'>
<a class='nav-link' routerLink='/request'>Request</a>
</div>
<div [ngClass]='{ "nav-item": true, active: pageTitle === "Volunteer" }'>
<a class='nav-link' routerLink='/volunteer'>Volunteer</a>
</div>
<div [ngClass]='{ "nav-item": true, active: pageTitle === "About" }'>
<a class='nav-link' routerLink='/about'>About</a>
</div>
</div>
</div>
Relevant part of controller:
// importing jquery from npm module
import * as $ from 'jquery';
// inside the controller class
ngOnInit() {
$('.nav-link').click(() => $('.collapse').collapse('toggle'));
}
Included scripts (in .angular-cli.json
):
"scripts": [
"../node_modules/jquery/dist/jquery.min.js",
"../node_modules/popper.js/dist/umd/popper.min.js",
"../node_modules/bootstrap/dist/js/bootstrap.min.js"
]
I've seen multiple questions just like this, but almost always the answers say to make sure jQuery is included before Bootstrap, and that Bootstrap is not included twice. Neither is the case here.
Other jQuery functionality (normal collapse functionality) is working properly. And the same error comes up if I try to do use the .dropdown()
function on dropdowns.
What is the issue here?
If you need: Angular 5, Bootstrap v4.0.0 (npm module), jQuery v3.3.1 (npm module)
回答1:
You need to use declare let $ : any;
instead of your import
I assume that if you use
import jquery as $ from 'jquery';
then it means that $ will only contain the code defined in the jquery package, and not the additional plugins declared by bootstrap (or by any other jquery plugins).
If you use
declare let $ : any;
then $ represents the normal jQuery function PLUS the additional plugins (collapse, dropdown, ...) added by other libraries
If you don't want to use any
, and you need to explicitely call some plugin methods, you need to extend jQuery's interface
interface JQuery
{
carousel(options : any);
}
declare let $: JQuery;
Note if you can avoid it, you should avoid using jquery or jquery plugins when a native angular approach is available
For boostrap, like ConnorsFan mentionned, you can use ng-bootstrap as a replacement. It requires bootstrap's CSS file, but dynamic components have been rewritten in native angular, without the need of jQuery
回答2:
After more research, I found this Stack Overflow answer that suggested adding the following line (replacing the import * as $ from 'jquery'
):
declare let $: any;
Unfortunately, I don't understand what this means or how it works, but it fixed the problem for me. Hope this helps someone.
回答3:
Use:
declare let $ : any;
Instead of:
import * as $ from 'jquery';
As a workaround you can use:
$('#yourId').removeClass('show');
(for others users)
Assure that you have the settings on angular.json
like on the question:
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/popper.js/dist/umd/popper.min.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
]
回答4:
When you are inside an Angular application there is no need for jQuery. You can use local variables instead. There is actually a very good example of how to do this in this stackblitz
回答5:
This worked for me
import * as $ from 'jquery';
declare var $:any;
In angular.json
"styles": [
"src/styles.css",
"node_modules/bootstrap3/dist/css/bootstrap.min.css",
"node_modules/ngx-toastr/toastr.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap3/dist/js/bootstrap.js"
]
Now you can use collapse in angular 7
$(".panel-collapse").collapse("hide");
来源:https://stackoverflow.com/questions/49821320/bootstrap-w-angular-error-collapse-is-not-a-function