Angular2应用程序在单击路线时冻结
我正在为我的实习开发Angular2应用程序,我的一个组件有一个真正的问题 该组件是应用程序的主导航菜单,是一个递归树视图,其中每个组件实例都包含到另一个组件的路径 这个组件可以很好地处理很少的子组件,但在实际用例中,大约有300个子组件是递归创建的。当我点击菜单上的一个项目以显示另一个视图时,应用程序冻结。处理这条路线似乎需要很长时间,而且我已经超时了 奇怪的是,导航菜单本身的构造没有问题,但当我试图点击一条路线时,它总是冻结 编辑:这里是plunker上的一些文件-> 这是我的递归组件:Angular2应用程序在单击路线时冻结,angular,angular2-routing,Angular,Angular2 Routing,我正在为我的实习开发Angular2应用程序,我的一个组件有一个真正的问题 该组件是应用程序的主导航菜单,是一个递归树视图,其中每个组件实例都包含到另一个组件的路径 这个组件可以很好地处理很少的子组件,但在实际用例中,大约有300个子组件是递归创建的。当我点击菜单上的一个项目以显示另一个视图时,应用程序冻结。处理这条路线似乎需要很长时间,而且我已经超时了 奇怪的是,导航菜单本身的构造没有问题,但当我试图点击一条路线时,它总是冻结 编辑:这里是plunker上的一些文件-> 这是我的递归组件: @
@Component({
selector: 'tran-location-zippy',
template : `<ul *ngIf="location">
<li class="li-item li-device-container"
[class.active]="isRouteActive(['LocationVueComponent', {code : location.code}])">
<a class="goTo"
[routerLink]="['LocationVueComponent', {code : location.code}]">
<span class="glyphicon glyphicon-new-window"></span>
</a>
<div (click)="toggle()">
<span *ngIf="!visible && !isEmpty()" class="glyphicon glyphicon-chevron-down"></span>
<span *ngIf="visible && !isEmpty()" class="glyphicon glyphicon-chevron-up"></span>
{{location.label}}
</div>
</li>
<span [hidden]="!visible">
<li *ngFor="#subLocation of location.children"
class="li-container">
<tran-location-zippy
[location]="subLocation">
</tran-location-zippy>
</li>
</span>
</ul>
`,
styleUrls : ['src/style/zippy-menu.style.css'],
directives: [
ROUTER_DIRECTIVES,
LocationZippyComponent
]
})
export class LocationZippyComponent {
@Input() location
visible : boolean
constructor(private _router : Router) {
this.visible = false
}
toggle() {
this.visible = !this.visible
}
isEmpty() : boolean {
return (this.location.hasOwnProperty('devices') || this.location.hasOwnProperty("children")) ? false : true
}
isRouteActive(route) : boolean {
return this._router.isRouteActive(this._router.generate(route))
}
};
以下是我的路线:
@RouteConfig([
{
path: '/',
name: 'DefaultVueComponent',
component: DefaultVueComponent,
useAsDefault : true
},
{
path: '/location/:code',
name: 'LocationVueComponent',
component: LocationVueComponent
},
{
path: '/devices/types/:label',
name: 'DeviceTypeVueComponent',
component: DeviceTypeVueComponent
},
{
path: '/device/:code',
name: 'DeviceVueComponent',
component: DeviceVueComponent
},
{
path: '/state/:label',
name: 'GlobalStateVueComponent',
component: GlobalStateVueComponent
}
])
这是我的视图,通过点击菜单项来调用,它是一个基本组件,调用2个子组件。孩子们根据查询输入从服务器获取信息
@Component({
selector: 'tran-location-vue',
template: `
<p>
<label for="refresh-button">
{{ ((refreshing) ? 'STOP_AUTO_RESFRESH' : 'START_AUTO_RESFRESH') | translate }}
</label>
<button id="refresh-button" type="button" class="btn btn-default" (click)="toggleRefreshButton()">
<span class="glyphicon glyphicon-refresh"></span>
</button>
</p>
<tran-global-state [queries]="[query]" [timingRefreshing]="5000" [refreshing]="refreshing">
</tran-global-state>
<tran-alarms-states [queries]="[query]" [timingRefreshing]="5000" [refreshing]="refreshing">
</tran-alarms-states>
`,
providers: [
CategoriesService
],
directives: [
GlobalStateComponent,
AlarmsStatesComponent
],
pipes: [
TranslatePipe
]
})
export class LocationVueComponent implements OnInit {
query : QueryString
refreshing : boolean
constructor(
private _routeParams : RouteParams
) {
this.refreshing = true
}
ngOnInit() {
let location = this._routeParams.get('code')
this.query = {key: 'location', value: location}
}
toggleRefreshButton() {
this.refreshing = !this.refreshing
}
}
@组件({
选择器:“传输位置vue”,
模板:`
{{((刷新)?'STOP_AUTO_RESFRESH':'START_AUTO_RESFRESH')翻译}
`,
供应商:[
分类服务
],
指令:[
全局状态组件,
报警状态组件
],
管道:[
平移体
]
})
导出类LocationVueComponent实现OnInit{
查询:查询字符串
刷新:布尔值
建造师(
专用路线图:路线图
) {
这是真的
}
恩戈尼尼特(){
让location=this.\u routeParams.get('code'))
this.query={key:'location',value:location}
}
toggleRefreshButton(){
this.refreshing=!this.refreshing
}
}
我找到了解决问题的方法。我将我的LocationZippyComponent
组件的changeDetection
策略更改为ChangeDetectionStrategy.OnPush
,不再冻结。我想Angular同时检测300个组件的变化是一个性能问题。似乎很有趣,你能把它放在plunker中吗?或者至少将组件LocationVueComponent
添加到您的问题中?@Abdulrahman我添加了我的LocationVueComponent
,如果您愿意,我还可以添加两个子组件,这将澄清问题。我认为问题最有可能出现在全局状态组件、AlarmsStatesComponent、TranslatePie、CategoriesService
之一。或者,在你得到回应之前,它会让你耳目一新。尝试将[timingRefreshing]=“5000”
增加到一个大数字。@Abdulrahman我在plunker上放了一些需要的文件。我试图增加刷新时间,但没有任何改变。我认为LocationZippyComponent
是我遇到问题的唯一组件,因为当我处理一个小数据库或一个大数据库,但禁用导航组件时,一切都正常。我真的不知道如何调试我的代码如果从LocationVueComponent
中删除tran全局状态
和tran报警状态
,问题还会发生吗?另外,如果您查看“网络”选项卡,是否有不正确的地方?喜欢太多的请求吗?还是一个需要太长时间的请求?此外,您提供的plunker不起作用,它只是代码。但是,我会尝试在其中重现你的问题
@Component({
selector: 'tran-location-vue',
template: `
<p>
<label for="refresh-button">
{{ ((refreshing) ? 'STOP_AUTO_RESFRESH' : 'START_AUTO_RESFRESH') | translate }}
</label>
<button id="refresh-button" type="button" class="btn btn-default" (click)="toggleRefreshButton()">
<span class="glyphicon glyphicon-refresh"></span>
</button>
</p>
<tran-global-state [queries]="[query]" [timingRefreshing]="5000" [refreshing]="refreshing">
</tran-global-state>
<tran-alarms-states [queries]="[query]" [timingRefreshing]="5000" [refreshing]="refreshing">
</tran-alarms-states>
`,
providers: [
CategoriesService
],
directives: [
GlobalStateComponent,
AlarmsStatesComponent
],
pipes: [
TranslatePipe
]
})
export class LocationVueComponent implements OnInit {
query : QueryString
refreshing : boolean
constructor(
private _routeParams : RouteParams
) {
this.refreshing = true
}
ngOnInit() {
let location = this._routeParams.get('code')
this.query = {key: 'location', value: location}
}
toggleRefreshButton() {
this.refreshing = !this.refreshing
}
}