angular 5: hur man importerar javascript specifikt för denna komponent. ska inte vara tillgänglig på andra komponenter


För närvarande

i game.component.ts (rutt: /play)

import '../../assets/js/game.js';

export class PlayComponent implements OnInit {
    constructor() { }

    ngOnInit() {
    }

}

game.js laddas utan problem och startar spelet på domain.com/play

Problemet

när jag laddar home.component.ts (rutt: /) importeras också spelskriptet och läggs till. Hur kan jag få spelskriptet att endast laddas på /play? Jag vet att jag kan lägga skriptet i en funktion och bara kalla på det i spelfuls komponenten men jag vill verkligen undvika att ladda för mycket JS där det inte behövs.

Svar #1

Jag tror inte att det finns ett "Angular"-sätt att uppnå det du vill förutom att pilla med Bootstrap/Webpack-processen.

Använd bara vanlig JavaScript.

Ladda skriptet inom ngOnInit-hooken i din PlayComponent. Med det tillvägagångssättet kommer skriptet bara att laddas när komponenten skapas. Du kan också ta bort skriptet i ngOnDestroy-hooken om du vill:

@Component({})
export class PlayComponent implements OnInit, OnDestroy {
    constructor(private assetService: AssetService) {}

    ngOnInit() {
        assetService.loadScript('/assets/js/game.js').then(data => {
            console.log(data); // {loaded: true, status: 'Loaded'}
        });
    }

    ngOnDestroy() {
        assetService.removeScript('/assets/js/game.js');
    }
}

@Injectable()
export class AssetService {
    removeScript(path: string) {
        // TODO: Remove DOM element that has attribute `data-path="${path}"`
    }

    loadScript(path: string): Promise<any> {
        return new Promise(resolve => {
            const script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = path;
            script.setAttribute('data-path', path);

            // IE
            if (script.readyState) {
                script.onreadystatechange = () => {
                    if (script.readyState === 'loaded' || script.readyState === 'complete') {
                        script.onreadystatechange = null;
                        resolve({ loaded: true, status: 'Loaded' });
                    }
                };
            } else {
                script.onload = () => {
                    resolve({ loaded: true, status: 'Loaded' });
                };
            }

            script.onerror = (error: any) => resolve({ loaded: false, status: 'Loaded' });
            document.getElementsByTagName('head')[0].appendChild(script);
        });
    }
}