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
    }

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'));
  }
}

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
    }

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');
  }

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


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


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));
});
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.