【发布时间】:2021-07-13 03:55:38
【问题描述】:
我一直在对 Angular 中的一个错误进行研发(不是称其为错误)。但是在 SPA 中,js 在路由到不同的组件后失去了作用域。我已经阅读了互联网上几乎所有可用的答案。让我以更简单的方式说明问题所在。
- 作用域在我们路由到不同的元素后结束(我们使用的是外部 js)
- 由于我的 js 是相互连接的,所以必须一次加载。所以通过 component.ts 方法加载特定的 js 是不可行的,因为它再次改变了 DOM 的范围并且其他功能停止工作。
所以如果有人遇到这样的问题,让我们在这里讨论。
我的代码:Script-loader.ts
从 '@angular/core' 导入 { Injectable }; @Injectable({
providedIn: 'root' }) 导出类 ScriptLoaderService {private scripts: any = {}; load(...scripts: string[]) { this.scripts = scripts; let promises: any[] = []; scripts.forEach((script) => promises.push(this.loadScript(script))); return Promise.all(promises); } loadScript(name: string) { return new Promise((resolve, reject) => { let script = (document.createElement('script') as any); script.type = 'text/javascript'; script.src = name; script.async = false; script.defer = false; if (script.readyState) { //IE script.onreadystatechange = () => { if (script.readyState === 'loaded' || script.readyState === 'complete') { script.onreadystatechange = null; resolve({script: name, loaded: true, status: 'Loaded'}); } }; } else { //Others script.onload = () => { resolve({script: name, loaded: true, status: 'Loaded'}); }; } script.onerror = (error: any) => resolve({script: name, loaded: false, status: 'Loaded'}); document.getElementsByTagName('head')[0].appendChild(script); }); }} 块引用
blogs.component.ts
从'@angular/core'导入{组件,OnInit,AfterViewInit}; 从'../script-loader.service'导入{ ScriptLoaderService }; 声明 var $: any;
@Component({ 选择器: 'app-blogs', templateUrl: './blogs.component.html', styleUrls: ['./blogs.component.css'] }) 导出类 BlogsComponent 实现 OnInit、AfterViewInit {
构造函数(私有脚本加载器:ScriptLoaderService){ }
ngAfterViewInit(): 无效 { this.scriptloader.load( '资产/js/app.js', '资产/数据/tipuedrop_content.js', '资产/js/global.js', 'assets/js/navbar-v1.js', '资产/js/main.js', 'assets/js/widgets.js',
'assets/js/lightbox.js', 'assets/js/feed.js', ); }ngOnInit(): 无效 { }
}
博客.module.ts
从'@angular/core'导入{ NgModule };
从“@angular/router”导入 { Routes, RouterModule };进口 { BlogsComponent } 来自 './blogs.component';
常量路由:Routes = [ { 小路: ””, 组件:博客组件}];
@NgModule({ 进口:[RouterModule.forChild(routes)],出口: [RouterModule] }) 导出类 BlogsModule { }
videos.component.ts
从'@angular/core'导入{组件,OnInit,AfterViewInit}; 从'../script-loader.service'导入{ ScriptLoaderService }; 声明 var $: any; @Component({ 选择器: 'app-videos',
templateUrl: './videos.component.html', styleUrls: ['./videos.component.css'] }) 导出类 VideosComponent 实现 OnInit, AfterViewInit {构造函数(私有脚本加载器:ScriptLoaderService){ }
ngAfterViewInit(): 无效 { this.scriptloader.load( '资产/js/app.js', '资产/数据/tipuedrop_content.js', '资产/js/global.js', 'assets/js/navbar-v1.js', 'assets/js/main.js','assets/js/widgets.js', 'assets/js/lightbox.js', 'assets/js/feed.js', ); }ngOnInit(): 无效 { }
}
videos.module.ts
从'@angular/core'导入{ NgModule };
从“@angular/router”导入 { Routes, RouterModule };进口 { VideosComponent } 来自 './videos.component';
常量路由:Routes = [ { 小路: ””, 组件:视频组件}];
@NgModule({ 进口:[RouterModule.forChild(routes)],出口: [RouterModule] }) 导出类 VideosModule { }
App-routing.module.ts
从'@angular/core'导入{ NgModule };进口{路由器模块, 来自'@angular/router'的路线};导入 { PreloadingStrategy,
PreloadAllModules } 来自“@angular/router”;导入 { BlogsModule } 来自'./blogs/blogs.module';导入 { FeedModule } 从 './feed/feed.module';导入 { HangoutModule } 从 './hangout/hangout.module';导入 { HomeModule } 从 './home/home.module';从导入 { VideosModule} './videos/videos.module';常量路由:Routes = [
{ 路径:“饲料”, loadChildren: "./feed/feed.module#FeedModule" }, { 路径:“阅读”, loadChildren: "./blogs/blogs.module#BlogsModule" }, { 路径:“观看”, loadChildren: "./videos/videos.module#VideosModule" }, { 路径:'家', loadChildren:"./home/home.module#HomeModule" }, { 路径:“环聊”, loadChildren:"./hangout/hangout.module#HangoutModule" }
];
@NgModule({ 导入:[RouterModule.forRoot(路由,{ preloadingStrategy: PreloadAllModules })], 出口: [RouterModule] }) 出口类 AppRoutingModule { }
现在当我从博客路由到视频时发生了什么。它再次添加了之前的所有js。我不知道这是否是一个好习惯。这是显示正在发生的事情的 DOM HEAD
附:没有适合您的确切解决方案。请在 component.ts 中编写您自己的 js。可以导入jquery,写qwery
【问题讨论】:
-
您是否想过将跨多个组件工作所需的任何 js 放入服务中,然后从服务中调用这些函数/变量?
-
我已经更新了代码。我使用了它,但它没有工作,我制作了一个 script.service.ts 文件并定义了函数,然后我使用 ngonit 调用它。那么由于js是相互关联的。这一切都必须一次加载。但它没有用。
-
嘿!我已经使用您的代码来实现和解决我的错误。它在一定程度上解决了它,但它再次在 DOM 中加载所有 js 文件。就像我在第一次刷新时有 3 个 js 文件(或 2 个脚本标签)一样。然后,如果我路由到另一个组件。它正在重新加载 js,但现在 HTML DOM 有 6 个脚本标签。如果你想让我分享代码,我会的。
-
它是这样显示的。只包含一个js文件。首次访问页面 。然后在路由到另一个组件时,它现在在字段中有 2 个相同的 js
标签: javascript angular routes angular-routing external-js