我正在为ImpressPages构建Angular(5.2.2)应用程序,我对HTTP请求有优化问题。我的应用程序结构如下所示:
container.component.html
<div *ngIf="layout">
<app-news *ngIf="layout == 'NewsComponent'" [hidden]="layout != 'NewsComponent'"></app-news>
<app-main *ngIf="layout == 'MainComponent'" [hidden]="layout != 'MainComponent'"></app-main>
<app-home *ngIf="layout == 'HomeComponent'" [hidden]="layout != 'HomeComponent'"></app-home>
</div>
container.component.ts
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-container',
templateUrl: './container.component.html',
})
export class ContainerComponent{
layout: string;
constructor(private route : ActivatedRoute) { }
ngOnInit() {
this.route.data.subscribe((response: {layout: string}) => {
this.layout = response.layout;
}, (error) => {
console.log(error);
})
}
}
main.component.ts
Home,News等其他组件看起来相同 - 只有用于API更改的URL和HTML中的布局
import { Component } from '@angular/core';
import { ActivatedRoute } from "@angular/router";
import { ServerService } from '../../services/server.service';
import { SeoService } from '../../services/seo.service';
import { Config } from '../../config';
interface pageData {
banner: string;
data: any;
html: string;
text: string;
title: string;
}
@Component({
selector: 'app-main',
templateUrl: './main.component.html',
providers: [Config, ServerService, SeoService]
})
export class MainComponent {
URL: string;
langUrl: string;
active: string;
pageData: pageData;
headerText: Object;
constructor(private config: Config, private route: ActivatedRoute, private service: ServerService, private seo: SeoService) {
this.URL = this.config.URL;
this.langUrl = this.config.getLanguage();
}
ngAfterViewInit(): void {
this.route.params.subscribe( params => {
if(params.lang != this.langUrl) {
this.langUrl = params.lang;
}
let siteTitle = params.index;
if(typeof siteTitle != 'undefined') {
siteTitle = siteTitle.replace('.html', ' ');
siteTitle = siteTitle.replace(/-/g,' ');
}
this.service.getResponse(`${this.URL}/getContent/${params.index}/${this.langUrl}/0`).subscribe(
(response: any) => {
this.pageData = response;
this.seo.generateTags({
lang: this.langUrl,
title : siteTitle,
image : `${this.URL}/file/repository/${this.pageData.banner}`,
slug : params.index
})
}, (error) => {
console.log(error);
}
);
});
}
}
还有问题。当我第一次加载网站时,HTTP请求如下所示:
然后,当我用其他布局(其他组件)转到其他页面时。每次我尝试进入和离开该页面时,HTTP请求都会增加1。首先输入:
还有一次:
(每当我清除网络标签时)
有没有更好的方法来实现我的想法?我需要在同一路径上管理组件取决于哪个布局API将返回,它必须是动态的。我无法创建/ home /:lang /:pageName或/ main /:lang /:pageName等链接。网址必须与ImpressPages CMS类似。
(服务工作者不会从API缓存数据 - 我还没有购买HTTPS,不要看它)
我希望我已经解释得很好。 谢谢你的回答。
修改
我现在遇到动态组件加载问题(https://angular.io/guide/dynamic-component-loader)。当我尝试通过 createComponent()方法执行此操作时,它会将我的组件数量增加一个。当我尝试通过 insert()方法执行此操作时,我收到错误:
`Cannot set property 'viewContainerParent' of undefined`
这是我的代码:
import { Component, ComponentFactoryResolver, ViewChild, ViewContainerRef } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { NewsComponent } from '../components/news/news.component';
import { MainComponent } from '../components/main/main.component';
import { HomeComponent } from '../components/home/home.component';
import { ContainerDirective } from '../directives/container.directive';
// Directive
import { AfterViewInit } from '@angular/core/src/metadata/lifecycle_hooks';
export const entryComponentsMap = {
'NewsComponent': NewsComponent,
'MainComponent': MainComponent,
'HomeComponent': HomeComponent
}; // Add Layout here
@Component({
selector: 'app-container',
templateUrl: './container.component.html',
})
export class ContainerComponent implements AfterViewInit{
@ViewChild('container', {read: ViewContainerRef}) container : ViewContainerRef;
layout: any;
component: any;
constructor(private route : ActivatedRoute, private componentFactoryResolver: ComponentFactoryResolver) {
}
ngOnInit() {
}
ngAfterViewInit() {
this.route.data.subscribe((response: {layout: string}) => {
this.layout = response.layout;
this.loadComponent(this.layout);
}, (error) => {
console.log(error);
})
}
loadComponent(layout) {
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(entryComponentsMap[layout]);
this.container.insert(entryComponentsMap[layout], 0);
this.component = this.container.createComponent(componentFactory);
}
ngOnChanges() {
console.log(this)
this.component.destroy();
}
}
任何解决方案?
答案 0 :(得分:0)
最后我找到了解决方案。路由参数订阅加载了两次。从一次加载的每3个组件发出请求。我刚刚使用unsubsribe()并在组件处于视图中时减少api调用。
工作示例:
import { Component } from '@angular/core';
import { ActivatedRoute } from "@angular/router";
import { Config } from "../../config";
import { ServerService } from "../../services/server.service";
import { SeoService } from "../../services/seo.service";
import { OnDestroy } from '@angular/core/src/metadata/lifecycle_hooks';
import { ISubscription } from 'rxjs/Subscription';
interface pageData {
banner: string;
data: any;
html: string;
text: string;
title: string;
}
@Component({
selector: 'app-news',
templateUrl: './news.component.html',
styleUrls: ['./news.component.less'],
providers : [Config, ServerService, SeoService],
})
export class NewsComponent implements OnDestroy {
subscription: ISubscription;
subscriptionHTTP: ISubscription;
URL: string;
langUrl: string;
active: string;
pageData: pageData;
headerText: Object;
constructor(private config: Config, private route: ActivatedRoute, private service: ServerService, private seo: SeoService) {
this.URL = this.config.impressURL;
this.langUrl = this.config.getLanguage();
this.subscription = this.route.params.subscribe( params => {
if(params.lang != this.langUrl) {
this.langUrl = params.lang;
}
let siteTitle = params.index;
if(typeof siteTitle != 'undefined') {
siteTitle = siteTitle.replace('.html', ' ');
siteTitle = siteTitle.replace(/-/g,' ');
}
this.subscriptionHTTP = this.service.getResponse(`${this.URL}/getContent/${params.index}/${this.langUrl}/0`).subscribe(
(response: any) => {
this.pageData = response;
this.seo.generateTags({
lang: this.langUrl,
title : siteTitle,
image : `${this.URL}/file/repository/${this.pageData.banner}`,
slug : params.index
})
}, (error) => {
console.log(error);
}
);
});
}
ngOnInit(): void {
}
ngOnDestroy() {
if(this.subscription) this.subscription.unsubscribe();
if(this.subscriptionHTTP) this.subscriptionHTTP.unsubscribe();
}
hideOnClick(element, target) {
element.parentNode.parentNode.classList.remove('in');
}
}
我也尝试过这种方式:https://angular.io/guide/dynamic-component-loader,但我的方式要快得多。组件在开始时加载,而不是在路由更改时加载。