Angular2 équivalent de $ document.ready ()

86

Question simple, j'espère.

Je veux exécuter un script lorsque l'équivalent Angular2 de $ document.ready () est déclenché. Quelle est la meilleure façon d'y parvenir?

J'ai essayé de mettre le script à la fin de index.html, mais comme je l'ai découvert, cela ne fonctionne pas! Je suppose qu'il doit entrer dans une sorte de déclaration de composant?

Est-il possible d'exécuter le chargement du script à partir d'un .jsfichier?

EDIT - Code:

J'ai les plugins js et css suivants injectés dans mon application (à partir du thème html Foundry ).

    <link href="css/themify-icons.css" rel="stylesheet" type="text/css" media="all" />
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css" media="all" />
    ...


    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/flexslider.min.js"></script>
    ...
    <script src="js/scripts.js"></script> //This initiates all the plugins

Comme indiqué, le script.js «instancie» le tout, et doit donc être exécuté une fois Angular prêt. script.js

Ça marche:

import {Component, AfterViewInit} from 'angular2/core';

@Component({
  selector: 'home',
  templateUrl: './components/home/home.html'
})
export class HomeCmp implements AfterViewInit {


    ngAfterViewInit() {
       //Copy in all the js code from the script.js. Typescript will complain but it works just fine
    }
Chris
la source
après quelques heures de recherche, j'ai toujours le même problème. > Module non trouvé: Erreur: Impossible de résoudre '@ types / jquery' Je l'ai installé avec npm install --save -D @ types / jquery, puis quand j'essaye de l'importer dans le module (en raison du fait que je a reçu un message de la boîte à outils qu'il ne connaît pas $ de jQuery) dans mon Component.ts il dit mon premier message! J'espère que mes explications sont correctes Merci encore pour toute l'aide que cette communauté m'a apportée! btw: Ceci est mon premier vrai message donc j'espère en écrire un bon
Alexandre Saison

Réponses:

37

Vous pouvez déclencher un événement vous-même dans ngOnInit()votre composant racine Angular, puis écouter cet événement en dehors d'Angular.

Ceci est du code Dart (je ne connais pas TypeScript) mais ne devrait pas être trop difficile à traduire

@Component(selector: 'app-element')
@View(
    templateUrl: 'app_element.html',
)
class AppElement implements OnInit {
  ElementRef elementRef;
  AppElement(this.elementRef);

  void ngOnInit() {
    DOM.dispatchEvent(elementRef.nativeElement, new CustomEvent('angular-ready'));
  }
}
Günter Zöchbauer
la source
OK parfait. Pourriez-vous fournir un exemple rapide d'un tel code? Désolé, mais tout à fait nouveau pour ng2
Chris
De préférence, j'aimerais pouvoir charger un fichier js lorsque l'onInit se produit. Ce fichier contient tout mon code de document prêt (à partir d'un modèle html que j'utilise) et est en js, donc je ne peux pas simplement le copier-coller puisque j'écris ng2 en .ts
Chris
Vérifiez la référence de ngOnInit.
Boris
1
@Boris ça ne m'amène pas très loin j'ai peur
Chris
9
Ensuite, vous exécutez simplement le code ngAfterViewInit() { ... }. Pas besoin de déclencher un événement.
Günter Zöchbauer
64

Copie de la réponse de Chris:

Ça marche:

import {AfterViewInit} from 'angular2/core';    

export class HomeCmp implements AfterViewInit {    

    ngAfterViewInit() {
       //Copy in all the js code from the script.js. Typescript will complain but it works just fine
    }
Sameer Alibhai
la source
4
Je ne sais pas pourquoi les votes négatifs. Cela a fonctionné pour moi, mais a également introduit une course entre le code JS hérité que j'essayais d'exécuter et le compilateur de vue. J'ai fini par utiliser AfterViewChecked, mais tout de même, voici un vote positif pour m'orienter dans la bonne direction.
lukiffer
1
Cela peut fonctionner, mais ce n'est peut-être pas la meilleure pratique. Ce qui serait mieux, c'est d'avoir tout le code externe enveloppé dans une fonction globale, mais bien espacée de noms, puis d'appeler cette fonction à partir de ngAfterViewInit(). Par exemple window.MY_APP = {}; MY_APP.init = function () {/*copy all that script.js here*/ }. Ensuite, dans votre composant, import ...; declare var MY_APP: any; class HomeComponent() { ngAfterViewInit() { MY_APP.init(); } }mais l' essentiel est toujours que vous n'avez pas d'application angular2 - votre script.js est essentiellement une page jquery à l'ancienne. Vous pouvez en transformer la majeure partie en composants NG2.
Zlatko
1
Je ne vote pas contre cela, mais dans cette méthode, je peux accéder aux éléments DOM. Cependant, lorsque j'essaye d'obtenir element.css ('height'), il me renvoie 0px Donc je ne peux pas l'utiliser pour définir le CSS.
Explosion du
Cela a parfaitement fonctionné pour moi :) Je pense qu'à ce stade, vous avez déjà DOM, mais vous n'avez peut-être pas encore toutes les sources chargées, comme les images. Donc c'est exactement comme $document.ready().
Affilnost
1
Doux et doux!
Sam
17

J'ai choisi cette solution pour ne pas avoir à inclure mon code js personnalisé dans le composant autre que la fonction jQuery $ .getScript .

Remarque: a une dépendance sur jQuery. Vous aurez donc besoin des typages jQuery et jQuery.

J'ai trouvé que c'est un bon moyen de contourner les fichiers js personnalisés ou du fournisseur qui n'ont pas de typages disponibles de cette façon TypeScript ne vous crie pas lorsque vous démarrez votre application.

import { Component,AfterViewInit} from '@angular/core'

@Component({
  selector: 'ssContent',
  templateUrl: 'app/content/content.html',
})
export class ContentComponent implements AfterViewInit  {

  ngAfterViewInit(){
    $.getScript('../js/myjsfile.js');
  }
}

Mettre à jour En fait, dans mon scénario, l'événement du cycle de vie OnInit fonctionnait mieux car il empêchait le script de se charger après le chargement des vues, ce qui était le cas avec ngAfterViewInit, et cela faisait que la vue affiche des positions d'élément incorrectes avant le chargement du script.

ngOnInit() {
    $.getScript('../js/mimity.js');
  }
dynamiclynk
la source
J'obtiens Cannot find name '$'.quand j'essaye de suivre cet exemple?
eat-sleep-code
3
@ eat-sleep-code Je pense que vous avez besoin des typages jQuery, pourquoi ne pas essayer npm install @types/jquery -D? : D
realappie
4

Pour utiliser jQuery dans Angular, déclarez uniquement le $ comme suit: declare var $: any;

Ilir Hushi
la source
où mettez-vous cela?
Dan Chase
@DanChase vous pouvez le placer après les importations des bibliothèques dans la classe
Ilir Hushi
jetez un oeil à ce bel article pour exclure jquery usinng angular-cli: medium.com/@swarnakishore/…
Pavel
3

la réponse acceptée n'est pas correcte et cela n'a aucun sens de l'accepter compte tenu de la question

ngAfterViewInit se déclenchera lorsque le DOM sera prêt

whine ngOnInit se déclenchera lorsque le composant de page commence à peine à être créé

phil123456
la source
1
Essayez d'être très clair uniquement sur votre solution dans votre réponse et si vous pensez qu'une réponse n'est pas correcte, envisagez plutôt de commenter cette question.
Zeeshan Adil
pas de problème, essayez simplement de rendre votre réponse plus claire pour aider plus de gens. avec un exemple de code minimaliste.
Zeeshan Adil
0

Dans votre fichier main.ts , bootstrap après DOMContentLoaded afin que angular se charge lorsque DOM est complètement chargé.

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}



document.addEventListener('DOMContentLoaded', () => {
  platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.log(err));
});
Vikas Kandari
la source