Angular2 equivalente a $ document.ready ()

86

Pregunta simple, espero.

Quiero ejecutar un script cuando se activa el equivalente Angular2 de $ document.ready (). ¿Cuál es la mejor manera de lograr esto?

Intenté poner el guión al final index.html, pero descubrí que esto no funciona. ¿Supongo que tiene que ir en algún tipo de declaración de componente?

¿Es posible ejecutar la carga del script desde un .jsarchivo?

EDITAR - Código:

Tengo los siguientes complementos js y css inyectados en mi aplicación (del tema html de 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

Como se señaló, scripts.js 'crea una instancia' de todo y, por lo tanto, debe ejecutarse después de que Angular esté listo. script.js

Lo tengo funcionando:

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
fuente
después de algunas horas de investigación, todavía tengo el mismo problema. > Módulo no encontrado: Error: No se puede resolver '@ types / jquery' Lo instalé con npm install --save -D @ types / jquery, luego cuando intento importarlo en el Módulo (debido al hecho de que recibí un mensaje de la caja de herramientas que no conoce $ de jQuery) en mi Component.ts ¡dice mi primer mensaje! Espero que mis explicaciones sean correctas. Gracias de nuevo por toda la ayuda que esta comunidad me brindó. Por cierto: Este es mi primer mensaje real, así que espero escribir uno bueno
Alexandre Saison

Respuestas:

37

Puede disparar un evento usted mismo en ngOnInit()su componente raíz Angular y luego escuchar este evento fuera de Angular.

Este es el código Dart (no sé TypeScript) pero no debería ser difícil de traducir

@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
fuente
OK perfecto. ¿Podría proporcionar un ejemplo rápido de dicho código? Lo siento, pero es bastante nuevo en ng2
Chris
Preferiblemente, me gustaría poder cargar un archivo js cuando se produce onInit. Este archivo tiene todo el código de mi documento listo (de una plantilla html que estoy usando) y está en js, por lo que no puedo copiarlo y pegarlo ya que estoy escribiendo ng2 en .ts
Chris
Consulte la referencia de ngOnInit.
Boris
1
@Boris, me temo que no me lleva muy lejos
Chris
9
Luego simplemente ejecuta el código en formato ngAfterViewInit() { ... }. No es necesario disparar un evento.
Günter Zöchbauer
64

Copiando la respuesta de Chris:

Lo tengo funcionando:

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
fuente
4
No estoy seguro de por qué los votos negativos. Esto funcionó para mí, pero también introdujo una carrera entre el código JS heredado que estaba tratando de ejecutar y el compilador de vistas. Terminé usando AfterViewChecked, pero de todos modos, aquí hay un voto a favor por señalarme en la dirección correcta.
lukiffer
1
Esto puede funcionar, pero puede que no sea la mejor práctica. Lo que sería mejor es tener todo el código externo envuelto en alguna función global, pero con un buen espacio de nombres, luego llamar a esta función desde ngAfterViewInit(). Ej window.MY_APP = {}; MY_APP.init = function () {/*copy all that script.js here*/ }. Luego, en su componente, import ...; declare var MY_APP: any; class HomeComponent() { ngAfterViewInit() { MY_APP.init(); } }pero la conclusión es que no tiene una aplicación angular2: su script.js es básicamente una página jquery de la vieja escuela. Podrías convertir la mayor parte en componentes NG2.
Zlatko
1
No voy a rechazar esto, pero con este método puedo alcanzar elementos DOM. Sin embargo, cuando intento obtener element.css ('height') me devuelve 0px, por lo que no puedo usarlo para configurar css.
Blast
Me funcionó perfectamente :) Creo que, en esta etapa, ya tienes DOM, pero es posible que aún no hayas cargado todas las fuentes, como imágenes. Entonces es exactamente igual $document.ready().
Affilnost
1
¡Dulce y suave!
Sam
17

Fui con esta solución para no tener que incluir mi código js personalizado dentro del componente que no sea la función jQuery $ .getScript .

Nota: depende de jQuery. Por lo tanto, necesitará mecanografiar jQuery y jQuery.

Descubrí que esta es una buena manera de sortear los archivos js personalizados o de proveedores que no tienen mecanografía disponible de esa manera, TypeScript no te grita cuando inicias tu aplicación.

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

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

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

Actualización En realidad, en mi escenario, el evento del ciclo de vida OnInit funcionó mejor porque impidió que el script se cargara después de que se cargaran las vistas, que fue el caso de ngAfterViewInit, y eso hace que la vista muestre posiciones incorrectas de los elementos antes de cargar el script.

ngOnInit() {
    $.getScript('../js/mimity.js');
  }
Dynamiclynk
fuente
Obtengo Cannot find name '$'.cuando trato de seguir este ejemplo?
código de comer-dormir
3
@ eat-sleep-code Creo que necesitas las mecanografías de jQuery, ¿qué tal si lo intentas npm install @types/jquery -D? : D
realappie
4

Para usar jQuery dentro de Angular solo declare $ como sigue: declare var $: any;

Ilir Hushi
fuente
donde pones esto
Dan Chase
@DanChase puede colocarlo después de las importaciones de las bibliotecas en la clase
Ilir Hushi
Eche un vistazo a este buen artículo para desligar jquery usando angular-cli: medium.com/@swarnakishore/…
Pavel
3

la respuesta aceptada no es correcta, y no tiene sentido aceptarla considerando la pregunta

ngAfterViewInit se activará cuando el DOM esté listo

whine ngOnInit se activará cuando el componente de la página esté empezando a crearse

phil123456
fuente
1
Intente ser muy claro solo acerca de su solución en su respuesta y si cree que alguna respuesta no es correcta, considere comentar esa pregunta.
Zeeshan Adil
no hay problema, solo trate de hacer su respuesta más clara para ayudar a más personas. con un ejemplo de código minimalista.
Zeeshan Adil
0

En su archivo main.ts , arranque después de DOMContentLoaded, por lo que angular se cargará cuando DOM esté completamente cargado.

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
fuente