web-dev-qa-db-fra.com

Comment puis-je rendre à nouveau un composant manuellement?

Je suis un nouveau venu dans Angular2, je suis habitué au cycle de digest Angular 1), ce qui signifie que si je mets à jour l'étendue d'une vue, je peux déclencher manuellement un résumé en appelant $scope.$digest() _ Cependant, je ne suis pas sûr de savoir comment faire cela dans Angular2, surtout que le nouveau framework n'a pas la liaison de données implicite que l'ancienne version avait.

Voici mon problème. J'ai une route qui charge un composant quand une URL avec un paramètre est touché:

// Router
export const AppRoutes : RouterConfig = [
    {
    path: 'my/:arg/view',
    component: MyComponent  
    }
]

Ensuite, j'ai ce composant:

// Component
export class MyComponent {
    constructor(private route : ActivatedRoute,
      private r : Router) {
    let id = parseInt(this.route.params['value'].id);
    console.log(id);
    // do stuff with id
    }

    reloadWithNewId(id:number) {
        this.r.navigateByUrl('my/' + id + '/view');
    }
}

Disons que je navigue vers l'URL /my/1/view. Il appellera le constructeur et le numéro 1 Sera enregistré. Cependant, si j'appelle reloadWithNewId avec un nouvel identifiant, reloadWithNewIf(2), le constructeur n'est pas appelé à nouveau. Comment recharger manuellement le composant?

22
dopatraman

Il ne devrait pas être nécessaire de recharger le composant. Il suffit de mettre à jour le modèle et la vue se met à jour:

export class MyComponent {
    constructor(private route : ActivatedRoute,
      private r : Router) {}

    reloadWithNewId(id:number) {
        this.r.navigateByUrl('my/' + id + '/view');
    }

    ngOnInit() {
      this.sub = this.route.params.subscribe(params => {
         this.paramsChanged(params['id']);
       });
    }

    paramsChanged(id) {
      console.log(id);
      // do stuff with id

    }
}
16
Günter Zöchbauer

Vous pouvez forcer angular2 à réinitialiser le composant en accédant à une autre URL, puis à revenir à celle de votre choix.

Voici ma solution de contournement simple en utilisant les méthodes de la classe Router (référence: https://angular.io/docs/ts/latest/api/router/index/Router-class.html )

Constructeur de composant:

constructor(private router: Router) {}

En modèle (exemple):

(click)="onTabChange(id)"

Puis à l'intérieur de la classe de composant:

onTabChange() {
  if (this.router.navigated === false) {
    // Case when route was not used yet
    this.router.navigateByUrl(`/module/${id}`);
  } else {
    // Case when route was used once or more
    this.router.navigateByUrl(`/index`).then(
      () => {
        this.router.navigateByUrl(`/module/${id}`);
      });
  }
}
13
Germaniero

Le constructeur ne sera pas appelé à nouveau lorsque vous mettez à jour les paramètres. Parce que la classe Component est déjà instanciée,

vous pouvez vous abonner aux changements de paramètres comme ci-dessous si vous voulez détecter le changement,

  constructor(route: ActivatedRoute) {
    route.params.subscribe(param => {
        let id = param['id '];
        // Do your stuff with id change.
    });
  }

J'espère que cela t'aides!!

3
Madhu Ranjan

Je pense que le changeDetectorRef est l'outil approprié pour ce travail:

[~ # ~] html [~ # ~]

<my-component *ngIf="!reloading"
              (loadNext)="onLoadNext()">
</my-component>

[~ # ~] ts [~ # ~]

  constructor(
    private cdr: ChangeDetectorRef
  ) { }

  onLoadNext() {
      this.reloading = true;
      this.cdr.detectChanges();
      this.reloading = false;
      this.cdr.detectChanges();
  }

Pourquoi voudriez-vous cela au lieu de "mettre à jour le modèle et la vue se met à jour", comme dans la réponse fournie par Günther? De cette façon, vous êtes sûr que le composant est réinitialisé et qu'il ne reste plus de valeurs antérieures. C'est pourquoi je trouve plus propre de le faire comme ça.

Exemple: https://stackblitz.com/edit/commatrainer-v1

0
bersling