Equivalente Angular2 de $ document.ready ()

86

Pergunta simples, espero.

Quero executar um script quando o equivalente Angular2 de $ document.ready () for disparado. Qual é a melhor maneira de conseguir isso?

Tentei colocar o script no final de index.html, mas como descobri, isso não funciona! Presumo que tenha que ir em algum tipo de declaração de componente?

É possível executar o carregamento do script de um .jsarquivo?

EDITAR - Código:

Eu tenho os seguintes plug-ins js e css injetados em meu aplicativo (a partir do tema 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

Conforme observado, o script.js 'instancia' a coisa toda e, portanto, precisa ser executado depois que o Angular estiver pronto. script.js

Funcionou:

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
fonte
depois de algumas horas de pesquisa, ainda tenho o mesmo problema. > Módulo não encontrado: Erro: Não é possível resolver '@ types / jquery' Eu instalei com npm install --save -D @ types / jquery, então quando tento importá-lo no Módulo (devido ao fato de que eu recebi uma mensagem da caixa de ferramentas que não conhece $ de jQuery) em meu Component.ts diz minha primeira mensagem! Espero que minhas explicações estejam corretas. Obrigado novamente por toda a ajuda que esta comunidade me deu! btw: Esta é minha primeira mensagem real, então espero escrever uma boa
Alexandre Saison

Respostas:

37

Você pode disparar um evento por conta própria em ngOnInit()seu componente raiz Angular e, em seguida, ouvir esse evento fora do Angular.

Este é o código Dart (não sei TypeScript), mas não deve ser tão difícil de traduzir

@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
fonte
Ok perfeito. Você poderia fornecer um exemplo rápido desse código? Desculpe, mas é muito novo para ng2
Chris
De preferência, gostaria de poder carregar um arquivo js quando o onInit ocorrer. Este arquivo tem todo o código pronto do meu documento (de um modelo html que estou usando) e está em js, então não posso simplesmente copiar e colar, pois estou escrevendo ng2 em .ts
Chris
Verifique a referência para ngOnInit.
Boris
1
@Boris não me leva muito longe, infelizmente
Chris
9
Então você apenas executa o código em ngAfterViewInit() { ... }. Não há necessidade de disparar um evento.
Günter Zöchbauer
64

Copiando a resposta de Chris:

Funcionou:

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
fonte
4
Não sei por que os votos negativos. Isso funcionou para mim, mas também introduziu uma corrida entre o código JS legado que eu estava tentando executar e o compilador de visualização. Acabei usando AfterViewChecked, mas mesmo assim, aqui está um voto positivo por me apontar na direção certa.
lukiffer 01 de
1
Isso pode funcionar, mas pode não ser a melhor prática. O que seria melhor é ter todo o código externo envolvido em alguma função global, mas com namespace adequado e, em seguida, chamar essa função de ngAfterViewInit(). Ex window.MY_APP = {}; MY_APP.init = function () {/*copy all that script.js here*/ }. Em seguida, em seu componente, import ...; declare var MY_APP: any; class HomeComponent() { ngAfterViewInit() { MY_APP.init(); } }mas o resultado final é que você não tem um aplicativo angular2 - seu script.js é basicamente uma página jquery da velha escola. Você pode transformar a maior parte em componentes NG2.
Zlatko
1
Não estou downvoting isso, mas com este método posso alcançar elementos DOM. No entanto, quando tento obter element.css ('height'), ele retorna para mim 0px, portanto, não posso usá-lo para definir css.
Blast de
Funcionou perfeitamente para mim :) Acho que, nesta fase, você já tem DOM, mas pode não ter ainda todas as fontes carregadas, como imagens. Então é exatamente assim $document.ready().
Affilnost
1
Doce e suave!
Sam
17

Escolhi essa solução para não precisar incluir meu código js personalizado dentro do componente, exceto a função jQuery $ .getScript .

Nota: Depende do jQuery. Portanto, você precisará das tipificações jQuery e jQuery.

Descobri que esta é uma boa maneira de contornar arquivos js personalizados ou de fornecedores que não têm tipificações disponíveis, de forma que o TypeScript não grite com você quando você iniciar o aplicativo.

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

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

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

Atualizar Na verdade, no meu cenário, o evento de ciclo de vida OnInit funcionou melhor porque impediu o script de carregar depois que as visualizações foram carregadas, que era o caso com ngAfterViewInit, e isso faz com que a visualização mostre posições incorretas dos elementos antes do carregamento do script.

ngOnInit() {
    $.getScript('../js/mimity.js');
  }
dynamiclynk
fonte
Eu entendo Cannot find name '$'.quando tento seguir este exemplo?
coma-durma-código de
3
@ eat-sleep-code Eu acho que você precisa das tipificações jQuery, que tal dar npm install @types/jquery -Duma chance? : D
realappie
4

Para usar o jQuery dentro do Angular, declare $ apenas como segue: declare var $: any;

Ilir Hushi
fonte
onde você coloca isso?
Dan Chase
@DanChase você pode colocá-lo após as importações das bibliotecas da classe
Ilir Hushi
dê uma olhada neste belo artigo para excluir jquery usinng angular-cli: medium.com/@swarnakishore/…
Pavel
3

a resposta aceita não é correta, e não faz sentido aceitá-la considerando a questão

ngAfterViewInit será acionado quando o DOM estiver pronto

whine ngOnInit será acionado quando o componente da página estiver apenas começando a ser criado

phil123456
fonte
1
Tente ser muito claro apenas sobre sua solução em sua resposta e se você acha que alguma resposta não está correta, considere comentar sobre essa questão.
Zeeshan Adil
Não há problema, apenas tente tornar sua resposta mais clara para ajudar mais pessoas. com um exemplo de código minimalista.
Zeeshan Adil
0

Em seu arquivo main.ts, inicialize após DOMContentLoaded, então o angular será carregado quando o DOM estiver totalmente carregado.

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
fonte