【发布时间】:2016-04-26 10:11:41
【问题描述】:
我正在尝试制作 Angular 2 + Rx.JS 5/Next 的演示应用。
我注意到每次切换路由时都会重新实例化我的组件。
这是根应用程序的代码:
import {bootstrap} from 'angular2/platform/browser';
import {HTTP_PROVIDERS} from 'angular2/http';
import {ROUTER_PROVIDERS} from 'angular2/router';
import {AppComponent} from './app.component.ts';
bootstrap(AppComponent, [HTTP_PROVIDERS, ROUTER_PROVIDERS]);
这是根组件的代码:
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {FirstComponent} from './app.first-component.ts';
import {SecondComponent} from './app.second-component.ts';
import {AppService} from "./app.services.ts";
@Component({
selector: 'my-app',
providers: [AppService, FirstComponent, SecondComponent],
directives: [FirstComponent, SecondComponent, ROUTER_DIRECTIVES],
template: `<h1>An Angular 2 App</h1>
<a [routerLink]="['First']">first-default</a>
<a [routerLink]="['Second']">second</a>
<router-outlet></router-outlet>`
})
@RouteConfig([
{path: '/', name: 'First', component: FirstComponent, useAsDefault: true},
{path: '/second', name: 'Second', component: SecondComponent}
])
export class AppComponent {
}
然后是第一个组件的代码(映射到/):
import {Component, OnInit, NgZone} from "angular2/core";
import {AppService} from "./app.services.ts";
import 'rxjs/Rx';
@Component({
selector: 'my-first',
template: `
<div>
<ul>
<li *ngFor="#s of someStrings">
a string: {{ s }}
</li>
</ul>
</div>`
})
export class FirstComponent implements OnInit {
zone:NgZone;
constructor(private appService:AppService) {
console.log('constructor', 'first');
this.zone = new NgZone({enableLongStackTrace: false});
}
someStrings:string[] = [];
ngOnInit() {
console.log('ngOnInit', 'first');
this.appService.refCounted.subscribe(
theStrings=> {
this.zone.run(() =>this.someStrings.push(...theStrings));
},
error=>console.log(error)
);
}
}
还有第二个组件(映射到/second):
import {Component, OnInit, NgZone} from "angular2/core";
import {AppService} from "./app.services.ts";
@Component({
selector: 'my-second',
template: `
<div>
<ul>
<li *ngFor="#s of someStrings">
a string: {{ s }}
</li>
</ul>
</div>`
})
export class SecondComponent implements OnInit {
zone:NgZone;
constructor(private appService:AppService) {
console.log('constructor', 'second');
this.zone = new NgZone({enableLongStackTrace: false});
}
someStrings:string[] = [];
ngOnInit() {
console.log('ngOnInit', 'second');
this.appService.refCounted.subscribe(
theStrings=> {
this.zone.run(() =>this.someStrings.push(...theStrings));
},
error=>console.log(error)
);
}
}
最后是应用服务(与这个问题的相关性稍差):
import {Injectable} from "angular2/core";
import {Observable} from "rxjs/Observable";
import {Subject} from "rxjs/Subject";
import 'rxjs/Rx';
@Injectable()
export class AppService {
constructor(){
console.log('constructor', 'appService');
}
someObservable$:Observable<string[]> = Observable.create(observer => {
const eventSource = new EventSource('/interval-sse-observable');
eventSource.onmessage = x => observer.next(JSON.parse(x.data));
eventSource.onerror = x => observer.error(console.log('EventSource failed'));
return () => {
eventSource.close();
};
});
subject$ = new Subject();
refCounted = this.someObservable$.multicast(this.subject$).refCount();
someMethod_() {
let someObservable$:Observable<string[]> = Observable.create(observer => {
const eventSource = new EventSource('/interval-sse-observable');
eventSource.onmessage = x => observer.next(JSON.parse(x.data));
eventSource.onerror = x => observer.error(console.log('EventSource failed'));
return () => {
eventSource.close();
};
});
return someObservable$;
}
}
所以为了调试First和Second组件的实例化,我在constructors/ngOnInit中添加了一个console.log:
我注意到每次通过单击链接更改路线时,我都会得到:
constructor first
ngOnInit first
constructor second
ngOnInit second
...
有人可以告知这是否是预期的行为吗?如果是这样,我怎样才能让 Angular2 只实例化我的组件一次?
请注意,我已明确要求 First 和 Second 组件通过在根级组件中添加 providers 数组来实例化。
附:这里是这个项目的 github 仓库:https://github.com/balteo/demo-angular2-rxjs/tree/WITH-ROUTER
编辑:
我仍在努力寻找解决此问题的方法。我的路由器或我的组件有问题。我已经将应用推送到githubhere希望有人可以提供建议。
【问题讨论】:
-
你找到解决方案了吗?