【问题标题】:Angular 4 routers not loading componentsAngular 4路由器不加载组件
【发布时间】:2019-01-14 22:30:18
【问题描述】:

我正在尝试为一家建筑公司构建一个 Angular 项目,为此我从一个正版网站下载了 html 模板。现在,我正在尝试将代码迁移到 Angular 4。我已经在我的项目中实现了路由器概念以导航到不同的页面。

下面是项目结构 -

src 
|_
   app
    |_aboutus
    |_home
    |_app_root(app.component.html)
  |_assets
  |_index.html

所以我已将我所有的 css 和外部 js 文件包含到 index.html 页面中,该页面将用于所有组件。在 app.component.html 中,我将导航栏放在下面

<router-outlet> </router-outlet>

标签。我在 home 和 aboutus 组件中有我的 html 代码。下面是我的 app.module.ts 文件 -

 imports: [
    BrowserModule,
    RouterModule.forRoot([
      {
         path: 'about-us',
         component: AboutusComponent
      },
      {
        path: 'home',
        component: HomeComponent
     },
     {
      path: '',
      component: HomeComponent
     }
   ])
  ]

现在,如果我运行 localhost:4200,它会默认呈现主组件的视图。当我点击 aboutus pae 时,它​​会呈现很少的文本并且无法加载动画。但是,如果我像这样直接点击 aboutus 页面(localhost:4200/about-us),它能够加载数据。我的问题是我在这里路由有什么问题? 代码参考 - https://github.com/chikun525/RetroBuildConNew

【问题讨论】:

  • 您需要查看 angular-cli 如何处理外部 css 和 js 文件
  • 我建议您使用stackblitz.com上的问题创建示例代码
  • 我不认为有人会分叉你的 repo 并将更改推送到你的代码,* 不适合这个

标签: html angular angular4-router


【解决方案1】:

您必须动态加载您的 javascript 文件:

DynamicScriptLoaderService

import { Injectable } from '@angular/core';

interface Scripts {
  name: string;
  src: string;
}

export const ScriptStore: Scripts[] = [
  { name: 'chartjs', src: 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js' },
  { name: 'random-gen', src: '../../../assets/js/random-num-generator.js' }
];

declare var document: any;

@Injectable()
export class DynamicScriptLoaderService {

  private scripts: any = {};

  constructor() {
    ScriptStore.forEach((script: any) => {
      this.scripts[script.name] = {
        loaded: false,
        src: script.src
      };
    });
  }

  load(...scripts: string[]) {
    const promises: any[] = [];
    scripts.forEach((script) => promises.push(this.loadScript(script)));
    return Promise.all(promises);
  }

  loadScript(name: string) {
    return new Promise((resolve, reject) => {
      if (!this.scripts[name].loaded) {
        //load script
        let script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = this.scripts[name].src;
        if (script.readyState) {  //IE
            script.onreadystatechange = () => {
                if (script.readyState === "loaded" || script.readyState === "complete") {
                    script.onreadystatechange = null;
                    this.scripts[name].loaded = true;
                    resolve({script: name, loaded: true, status: 'Loaded'});
                }
            };
        } else {  //Others
            script.onload = () => {
                this.scripts[name].loaded = true;
                resolve({script: name, loaded: true, status: 'Loaded'});
            };
        }
        script.onerror = (error: any) => resolve({script: name, loaded: false, status: 'Loaded'});
        document.getElementsByTagName('head')[0].appendChild(script);
      } else {
        resolve({ script: name, loaded: true, status: 'Already Loaded' });
      }
    });
  }

}

在component.ts中

// Angular
import { Component, OnInit } from '@angular/core';

// Service
import { DynamicScriptLoaderService } from '../../shared/services/dynamic-script-loader.service';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html'
})
export class DashboardComponent implements OnInit {


  constructor(private dynamicScriptLoader: DynamicScriptLoaderService) {}

  ngOnInit() {
    // Just call your load scripts function with scripts you want to load
    this.loadStripeScripts();
  }

  private loadChartScripts() {
    // You can load multiple scripts by just providing the key as argument into load method of the service
    this.dynamicScriptLoader.load('chartjs','random-num').then(data => {
      // Script Loaded Successfully
    }).catch(error => console.log(error));
  }

}

并且不要忘记将服务添加到您的 app.module

providers: [
        DynamicScriptLoaderService
    ],

来源:https://medium.com/@zainzafar/angular-load-external-javascript-file-dynamically-3d14dde815cb

编辑:

这里有一个解决方法: 在要执行的 Javascript 文件中,将该文件的所有代码放在一个函数中,例如:

function myFunction() {
    alert("hello world");
    // here's goes all the javascript code
}

在您的组件(AboutusComponent)的 html 文件中将以下标签放在某处:

<button onclick="myFunction()" id="scriptCall" style="display: none"></button>

并在组件(AboutusComponent)的 ngOnInit 方法中放入以下代码

 var scriptCall = document.getElementById('scriptCall');
 scriptCall.click();

【讨论】:

  • 抱歉我的回复晚了。我尝试了上述方法,但得到了相同的结果。当我们路由到任何页面时,似乎 dom 元素被删除了。知道这里有什么工作吗?我苦苦挣扎了很久。
  • 我不明白这是如何回答这个问题的。好的代码....但是您添加了不必要的复杂性
最近更新 更多