Угловая маршрутизация вложенных компонентов

У меня есть компонент navbar, который имеет один routerLink

 <p>
  <a routerLink="/user">User</a>
</p>

и вложенный компонент под UserComponent, которому я передаю значение

@Component({
  selector: 'app-user',
  template: `
    <input #box (keyup.enter)="onEnter(box.value)">
    <div *ngIf="box.size > 0">
      <app-order [value]="value"></app-order>
    </div>`

})
export class UserComponent implements OnInit {

  value = '';

  onEnter(value: string) {
    this.value = value;
  }

  constructor() {
  }

  ngOnInit() {
  }

}

OrderComponent

@Component({
  selector: 'app-order',
  template:`{{id}}`
})
export class OrderComponent implements OnInit {

  @Input() id:String;

  constructor() { }

  ngOnInit() {
  }

}

Теперь, когда я ввожу ссылку пользователя, я получаю свое представление со ссылкой и моим переданным значением. Когда я снова нажимаю на ссылку, я получаю ту же страницу со значением. Как я могу изменить это поведение, чтобы при повторном нажатии на кнопку маршрута я получал ввод без переданного значения?

1 ответ

Решение

Я сталкивался с той же проблемой, когда пытался обновить страницу, нажимая соответствующую кнопку на панели навигации.

Angular утверждает, что навигация по тому же URL-адресу не имеет никакого эффекта, поскольку состояние приложения представлено его текущим URL-адресом.

Для этого есть обходной путь: onSameUrlNavigation

К сожалению, эта опция позволяет только защитникам и распознавателям снова запускаться при переходе по тому же URL, поэтому, если вы активируете его, вы заметите... вообще ничего!

Поэтому я создал свой собственный обходной путь с этим классом:

/**
 * Abstract class that allows derived components to get refreshed automatically on route change.
 * The actual use case is : a page gets refreshed by navigating on the same URL and we want the rendered components to refresh
 */
export abstract class AutoRefreshingComponent implements OnInit, OnDestroy {
  public routerEventsSubscription: Subscription;
  protected router: Router;

  constructor() { 
    this.router = AppInjector.get(Router);
  }

  /**
   * Initialization behavior. Note that derived classes must not implement OnInit.
   * Use initialize() on derived classes instead.
   */
  ngOnInit() {
    this.initialize();
    this.routerEventsSubscription = this.router.events.filter(x => x instanceof NavigationEnd).subscribe(res => {
      this.initialize();
    });
  }

  /**
   * Destruction behavior. Note that derived classes must not implement OnDestroy.
   * Use destroy() on derived classes instead.
   */
  ngOnDestroy(): void {
    this.routerEventsSubscription.unsubscribe();
    this.destroy();
  }

  /**
   * Function that allows derived components to define an initialization behavior
   */
  abstract initialize(): void;

  /**
   * Function that allows derived components to define a destruction behavior
   */
  abstract destroy(): void;

}

AppInjector относится к этому:

import {Injector} from '@angular/core';

/**
 * Allows for retrieving singletons using `AppInjector.get(MyService)` (whereas
 * `ReflectiveInjector.resolveAndCreate(MyService)` would create a new instance
 * of the service).
 */
export let AppInjector: Injector;

/**
 * Helper to access the exported {@link AppInjector}, needed as ES6 modules export
 * immutable bindings; see http://2ality.com/2015/07/es6-module-exports.html
 */
export function setAppInjector(injector: Injector) {
    if (AppInjector) {
        // Should not happen
        console.error('Programming error: AppInjector was already set');
    }
    else {
        AppInjector = injector;
    }
}

И в вашем AppModule:

import { setAppInjector } from './app.injector';

// ...

export class AppModule {
  constructor(private injector: Injector) {
    setAppInjector(injector);
  }
}

Затем продлите все необходимые компоненты AutoRefreshingComponent,

В твоем случае:

@Component({
  selector: 'app-user',
  template: `
    <input #box (keyup.enter)="onEnter(box.value)">
    <div *ngIf="box.size > 0">
      <app-order [value]="value"></app-order>
    </div>`

})
export class UserComponent extends AutoRefreshingComponent {

  value = '';

  onEnter(value: string) {
    this.value = value;
  }

  constructor() {
  }

  initialize() {
     // Reset your box value
  }

  destroy() {
  }

}

Это может быть излишним для того, чего вы хотите достичь, но будет полезно каждый раз, когда вы захотите обновить компонент в той же навигации по URL.

Позвольте мне знать, если это помогает.

Другие вопросы по тегам