Je suis nouveau sur Bootstrap et j'essaie d'activer la fonction .collapse() à partir de Javascript dans un contrôleur angulaire lorsqu'un utilisateur clique sur un lien. Cela devrait fermer la barre de navigation pliable lorsque l'un des liens est cliqué (car le routage est contrôlé par Angular et ne provoque pas de rafraîchissement de la page).

L'erreur suivante s'affiche:

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)

Partie pertinente du modèle HTML:

<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>

Partie pertinente du contrôleur:

// importing jquery from npm module
import * as $ from 'jquery';

// inside the controller class
ngOnInit() {
  $('.nav-link').click(() => $('.collapse').collapse('toggle'));
}

Scripts inclus (dans .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"
]

J'ai vu plusieurs questions comme celle-ci, mais presque toujours les réponses disent que jQuery est inclus avant Bootstrap et que Bootstrap n'est pas inclus deux fois. Ce n'est pas non plus le cas ici.

Les autres fonctionnalités jQuery (fonctionnalité de repli normal) fonctionnent correctement. Et la même erreur apparaît si j'essaie d'utiliser la fonction .dropdown() dans les listes déroulantes.

Quel est le problème ici?


Si vous avez besoin: Angular 5, Bootstrap v4.0.0 (module npm), jQuery v3.3.1 (module npm)

3
Jonathan Lam 13 avril 2018 à 19:18

5 réponses

Meilleure réponse

Vous devez utiliser declare let $ : any; au lieu de votre importation

Je suppose que si vous utilisez

import jquery as $ from 'jquery';

Cela signifie que $ ne contiendra que le code défini dans le package jquery, et non les plugins supplémentaires déclarés par bootstrap (ou par tout autre plugin jquery).

Si tu utilises

declare let $ : any;

Alors $ représente la fonction jQuery normale PLUS les plugins supplémentaires (collapse, dropdown, ...) ajoutés par d'autres bibliothèques

Si vous ne souhaitez pas utiliser any et que vous devez appeler explicitement certaines méthodes de plug-in, vous devez étendre l'interface jQuery

interface JQuery 
{
    carousel(options : any);
}

declare let $: JQuery;

Remarque si vous pouvez l'éviter, vous devez éviter d'utiliser jquery ou les plugins jquery lorsqu'une approche angulaire native est disponible

Pour boostrap, comme ConnorsFan l'a mentionné, vous pouvez utiliser ng-bootstrap en remplacement. Il nécessite le fichier CSS de bootstrap, mais les composants dynamiques ont été réécrits en angulaire natif, sans avoir besoin de jQuery

5
Jonathan Lam 30 déc. 2018 à 16:08

Cela a fonctionné pour moi

import * as $ from 'jquery';
declare var $:any;

Dans 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"
        ]

Vous pouvez maintenant utiliser l'effondrement en angulaire 7

 $(".panel-collapse").collapse("hide");
0
Aswathi Chandran 20 nov. 2019 à 10:29

Utilisation:

declare let $ : any;

Au lieu de:

import * as $ from 'jquery';

Pour contourner ce problème, vous pouvez utiliser:

$('#yourId').removeClass('show');

(pour les autres utilisateurs)

Assurez-vous que vous disposez des paramètres sur angular.json comme sur la 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"
 ]
0
Miguel Matos 21 oct. 2019 à 16:05

Lorsque vous êtes dans une application angulaire, jQuery n'est pas nécessaire. Vous pouvez utiliser des variables locales à la place. Il existe en fait un très bon exemple de la façon de procéder dans ce stackblitz

0
zmanc 13 avril 2018 à 17:37

Après plus de recherches, j'ai trouvé cette réponse Stack Overflow qui suggérait d'ajouter la ligne suivante (en remplaçant le import * as $ from 'jquery'):

declare let $: any;

Malheureusement, je ne comprends pas ce que cela signifie ni comment cela fonctionne, mais cela a résolu le problème pour moi. J'espère que cela aide quelqu'un.

1
Jonathan Lam 13 avril 2018 à 16:52