¿Por qué mis componentes angular2 se vuelven a crear cada vez que cambio la ruta?

Estoy tratando de armar una aplicación de demostración de Angular 2 Rx.JS 5 / Next.

Noté que mis componentes se vuelven a crear cada vez que cambio la ruta.

Aquí está el código para la aplicación raíz:

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]);

Aquí está el código para el componente raíz:

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 {
}

Luego, el código para el primer componente (asignado a /):

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)
        );
    }
}

Y el segundo componente (asignado a / segundo):

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)
        );
    }
}

Y finalmente, el servicio de la aplicación (un poco menos relevante para esta pregunta):

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$;
    }
}

Entonces, para depurar la creación de instancias de los componentes Primero y Segundo, he agregado un console.log en los constructores / ngOnInit:

y noté que cada vez que cambio la ruta haciendo clic en los enlaces, obtengo:

constructor first
ngOnInit first

constructor second
ngOnInit second
...

¿Alguien puede aconsejar si este es un comportamiento esperado? Si es así, ¿cómo puedo obtener Angular2 para instanciar mis componentes solo una vez?

Tenga en cuenta que he requerido explícitamente que los componentes Primero y Segundo se instancian en el componente de nivel raíz agregando una matriz de proveedores allí.

PD Aquí está el repositorio de github para este proyecto: https://github.com/balteo/demo-angular2-rxjs/tree/WITH-ROUTER

editar:

Todavía estoy tratando de encontrar una solución a este problema. Tengo un problema con el enrutador o mis componentes. He introducido la aplicación en github here con la esperanza de que alguien pueda brindar consejos.

Mejor respuesta
> = 2.3.0-rc.0

Se puede implementar una RouteReuseStrategy personalizada para controlar cuándo los componentes enrutados se destruyen y se recrean o reutilizan.

> https://angular.io/docs/ts/latest/api/router/index/RouteReuseStrategy-class.html
> https://www.softwarearchitekt.at/post/2016/12/02/sticky-routes-in-angular-2-3-with-routereusestrategy.aspx
> https://github.com/angular/angular/issues/7757

> = 2.0.0

CanReuse ya no existe en el nuevo enrutador. Cuando solo cambian los parámetros de la ruta mientras permanece en la misma ruta, el componente no se recrea.

Si se cambia la ruta y se navega de regreso al mismo componente, el componente se recrea.

< = RC.x

Note that I have explicitly required that the First and Second components be instantiated at the root-level component by adding a providers array there.

Agregar componentes a los proveedores: [] no tiene mayor sentido, especialmente en lo que respecta a este problema.

Puedes implementar CanReuse

añadiendo

routerCanReuse(next: ComponentInstruction, prev: ComponentInstruction) { return true; }

a su componente, pero es bastante limitado para qué tipo de navegación se reutiliza la misma instancia (si permanece en la misma ruta y solo cambia los parámetros).

Si CanReuse no soluciona su problema, mueva los datos a un servicio, donde se guardan las instancias y vincule la vista del componente a los datos de este servicio para que el componente muestre los datos actuales.

Por favor indique la dirección original:¿Por qué mis componentes angular2 se vuelven a crear cada vez que cambio la ruta? - Código de registro