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.