Как обновить компонент в Angular

86

Я работаю над проектом Angular. У меня проблемы с обновлением компонента.

Я хочу обновить компоненты маршрутизатора нажатием кнопки. У меня появляется кнопка обновления, когда я нажимаю на нее, компонент / маршрутизатор необходимо обновить.

Я пробовал, window.location.reload()и location.reload()эти два мне не подходят. Пожалуйста, помогите, если кто-нибудь знает об этом.

Шрихари Баллампалли
источник
Можете ли вы поделиться своим кодом в этом вопросе? что вы пробовали.
Chandru
это сложный код, в нем N строк кода, которым трудно поделиться
Шрихари Баллампалли
@Saurabh, обычно не требуется перезагружать компонент. Вы можете иметь функцию (например, вызвать «перезапуск») и вызывать функцию в кнопке «Обновить». Если вам нужно подписаться на изменение пути или другую службу, используйте функцию ngOnInit - ваш компонент должен расширять OnInit-, а не конструктор
Eliseo
Это то, что я сделал с Angular 9 stackoverflow.com/a/60909777/1072395
Wlada

Ответы:

115

После некоторого исследования и изменения моего кода, как показано ниже, сценарий у меня сработал. Я просто добавил условие:

this.router.navigateByUrl('/RefreshComponent', { skipLocationChange: true }).then(() => {
    this.router.navigate(['Your actualComponent']);
}); 
Шрихари Баллампалли
источник
1
Я использую это в инъекционной службе. Я заменил "your actualComponent"на переменную. Переменная установлена ​​в значение this.location.path()перед вызовом navigateByUrl. Таким образом, не нужно передавать какие-либо параметры от вызывающего компонента или дублировать / передавать маршруты.
Tewr
4
не могли бы вы объяснить, что такое RefrshComponent и Your actualComponent?
reverie_ss
15
Почти все будут в порядке, используя '/'where /RefrshComponentis, и [Your actualComponent"]вам просто нужно передать URL-адрес (и / или параметры), который вы хотите перезагрузить, например this.router.navigate(["/items"]). Этот взлом, по сути, перенаправляет на верхний URL-адрес, а затем очень быстро возвращается к предполагаемому URL-адресу, который незаметен для большинства пользователей и, по-видимому, является самым элегантным взломом для простого достижения этой цели.
softly
2
Я согласен, что это определенно должно сработать ... но в моем приложении (Angular 6) это не работает. Если я использую в '/'качестве фиктивного маршрута, он идет (через redirectTo) туда, где мой app-routing.module.ts перенаправляется на путь ''(пустая строка) и останавливается, не переходя к маршруту завершения в navigate()вызове. Если я использую несуществующую строку (например /foo) в качестве фиктивного маршрута, она идет (через redirectTo) туда, где мой app-routing.module.ts перенаправляет **(все остальное), и снова останавливается, не переходя на реальный маршрут. Любопытно, что строка URL-адреса ДЕЙСТВИТЕЛЬНО меняется на реальный маршрут. Есть мысли о том, что здесь другого?
Майкл Соренс
1
это может вызвать бесконечный цикл перенаправления, если не использовать его осторожно
Томас Кац
66

Используйте this.ngOnInit (); чтобы перезагрузить тот же компонент вместо перезагрузки всей страницы !!

DeleteEmployee(id:number)
  {
    this.employeeService.deleteEmployee(id)
    .subscribe( 
      (data) =>{
        console.log(data);

        this.ngOnInit();

      }),
      err => {
        console.log("Error");
      }   
  }
Шиной Бабу
источник
7
Хотя это может ответить на вопрос авторов, в нем отсутствуют некоторые поясняющие слова и / или ссылки на документацию. Фрагменты необработанного кода не очень полезны без некоторых фраз. Вы также можете найти очень полезным, как написать хороший ответ . Пожалуйста, отредактируйте свой ответ.
hellow
1
Это лучший ввод, чем выбранный ответ, но ему не хватает объяснения. В моем конкретном случае мне пришлось обновить дочерний компонент. В этом случае есть несколько способов, но рекомендуется использовать службу или транслировать событие от родителя к потомку.
Клаудио
5
Согласен, это работает только в том случае, если вы хотите обновить компонент изнутри компонента - если вы имеете дело с дочерними / внешними компонентами this.ngOnInit () не будет работать
astro8891
3
Несмотря на то, что он работает для компонента, он не сбрасывает валидаторы формы.
Vicky Gonsalves
1
Отлично работает, спасибо. Что касается объяснения AFAIC, код говорит само за себя.
Мартон Татаи
27

Добавление этого кода в конструктор необходимого компонента сработало для меня.

this.router.routeReuseStrategy.shouldReuseRoute = function () {
  return false;
};

this.mySubscription = this.router.events.subscribe((event) => {
  if (event instanceof NavigationEnd) {
    // Trick the Router into believing it's last link wasn't previously loaded
    this.router.navigated = false;
  }
});

Убедитесь, что unsubscribeиз этой моей подписки в ngOnDestroy().

ngOnDestroy() {
  if (this.mySubscription) {
    this.mySubscription.unsubscribe();
  }
}

Обратитесь к этой теме для получения более подробной информации - https://github.com/angular/angular/issues/13831

Санкар
источник
15

К счастью, если вы используете Angular 5.1+, вам больше не нужно внедрять хакерство, поскольку была добавлена ​​встроенная поддержка. Вам просто нужно установить onSameUrlNavigation на «перезагрузку» в параметрах RouterModule:

@ngModule({
 imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: ‘reload’})],
 exports: [RouterModule],
 })

Более подробную информацию можно найти здесь: https://medium.com/engineering-on-the-incline/reloading-current-route-on-click-angular-5-1a1bfc740ab2

Люцианский молдавский
источник
Вы также можете использовать router.onSameUrlNavigation = 'reload'свойство внедренного маршрутизатора.
0zkr PM
4
При использовании angular 6 для меня это не имело значения, то есть компонент не перезагружался. Однако принятый ответ работает.
Tewr
4
Хотя это не совсем ясно в документации, onSameUrlNavigationоно предназначено для повторного вызова Guard / Resolvers, а не для перезагрузки уже маршрутизированных компонентов. См. Github.com/angular/angular/issues/21115 для получения дополнительной информации. Это решение будет работать для более крупных и сложных приложений, использующих Guards / Resolvers, но не работает для простых примеров.
softly
1
да, onSameUrlNavigation снова запустит события навигации, но это не перезагрузит компонент
Paul Story
6

это немного нестандартно, и я не знаю, поможет ли это вам или нет, но я пробовал

this.ngOnInit();

это функция, поэтому любой код, который у вас есть, будет вызван как обновление.

Вадапалли Чайту
источник
3

Еще один способ без явного маршрута:

async reload(url: string): Promise<boolean> {
  await this.router.navigateByUrl('.', { skipLocationChange: true });
  return this.router.navigateByUrl(url);
}
Феликс
источник
2

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

this.router.navigateByUrl('/SampleComponent', { skipLocationChange: true });
this.router.navigate(["yourLandingComponent"]);
Саджитаран
источник
SampleComponent означает, что это должен быть пустой компонент или другой компонент в моем проекте?
Sreehari Ballampalli
он должен быть фиктивным, может быть пустым
Саджитаран
Хорошо, я попробую это
Sreehari Ballampalli
если я даю true, я получаю сообщение об ошибке: [ts] Тип 'true' не имеет общих свойств с типом 'NavigationExtras'
Sreehari Ballampalli
@SreehariBallampalli, проверьте обновленный ответ, вам нужно передать объект {skipLocationChange: true}
Саджитаран,
2

В моем приложении у меня есть компонент, и все данные поступают из API, который я вызываю в конструкторе компонента. Есть кнопка, с помощью которой я обновляю данные своей страницы. при нажатии кнопки у меня есть данные для сохранения и обновления данных. Итак, чтобы перезагрузить / обновить компонент - в соответствии с моими требованиями - нужно только обновить данные. если это также ваше требование, используйте тот же код, который написан в конструкторе компонента.

Bh00shan
источник
2

просто сделайте это: (для angular 9)

import { Inject } from '@angular/core';    
import { DOCUMENT } from '@angular/common';

constructor(@Inject(DOCUMENT) private document: Document){ }

someMethode(){ this.document.location.reload(); }
Реза Пири
источник
3
Пожалуйста, прочтите комментарий ОП, обновление всей страницы для него не вариант, это в первую очередь
лишает смысла использование angular
Вопрос касается перезагрузки только компонента, а не всей страницы.
Santosh
1

kdo

// reload page hack methode

push(uri: string) {
    this.location.replaceState(uri) // force replace and no show change
    await this.router.navigate([uri, { "refresh": (new Date).getTime() }]);
    this.location.replaceState(uri) // replace
  }
Жюльен Руссе
источник
1
constructor(private router:Router, private route:ActivatedRoute ) { 
}

onReload(){
 this.router.navigate(['/servers'],{relativeTo:this.route})
}
Бехзад Бехзад
источник
0

html файл

<a (click)= "getcoursedetails(obj.Id)" routerLinkActive="active" class="btn btn-danger">Read more...</a>

ts файл

  getcoursedetails(id)
  { 
  this._route.navigateByUrl('/RefreshComponent', { skipLocationChange: true }).then(() => {
    this._route.navigate(["course",id]);
  }); 
Харишанкер Маурья
источник
0

Просто измените routeReuseStrategy с углового маршрутизатора:

this._router.routeReuseStrategy.shouldReuseRoute = function () {
      return false;
    };

Установите для свойства routerproperty "navigated" значение false:

this._router.navigated = false;

Затем перейдите к своему компоненту:

this._router.navigate(['routeToYourComponent'])

После этого восстановите старый / стандартный routeReuseStrategy:

this._router.routeReuseStrategy.shouldReuseRoute = function (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
          return future.routeConfig === curr.routeConfig;

Вы также можете сделать из этого услугу:

@Injectable({
  providedIn: 'root'
})
export class RouterService {

  constructor(
    private _activatedRoute: ActivatedRoute,
    private _router: Router
  ) { }

  reuseRoutes(reuse: boolean) {
    if (!reuse) {
      this._router.routeReuseStrategy.shouldReuseRoute = function () {
        return false;
      };
    }
    if (reuse) {
      this._router.routeReuseStrategy.shouldReuseRoute = function (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        return future.routeConfig === curr.routeConfig;
      };
    }
  }

  async refreshPage(url?: string) {
    this._router.routeReuseStrategy.shouldReuseRoute = function () {
      return false;
    };

    this._router.navigated = false;

    url ? await this._router.navigate([url]) : await this._router.navigate([], { relativeTo: this._activatedRoute });

    this._router.routeReuseStrategy.shouldReuseRoute = function (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
      return future.routeConfig === curr.routeConfig;
    };
  }
}
Tombalabomba
источник
0

В моем случае я хотел refresh the whole pageвместо простого компонента, вот как я это сделал

window.location.reload();

Зохаб Али
источник
0

router.navigate['/path']будет перенесет вас только по указанному пути
использования router.navigateByUrl('/path')
его перезагружает всю страницу

Харприт Сингх
источник
-3

Другой способ обновить (сложный способ) страницу в angular 2, как это , выглядит как f5

import { Location } from '@angular/common';

constructor(private location: Location) {}

pageRefresh() {
   location.reload();
}
Чираг соратия
источник
1
Он сказал, что перезагрузка всей страницы не подходит, это перезагружает всю страницу, а не только один / несколько компонентов.
Милан Велебит
В итоге я использовал это, за исключением того, что у службы определения местоположения angular нет перезагрузки, поэтому я использовал window.
Paul Story