Я хочу определить, когда страница обновляется с помощью маршрутизатора в моем одностраничном приложении (проект Angular)
Есть ли альтернативный способ?
Приложение Angular — это одностраничное приложение, и в контексте одностраничного приложения полное приложение загружается один раз, а данные или экраны обновляются по мере того, как пользователь использует ваше приложение.
Обновление браузера эквивалентно закрытию приложения и его повторному запуску. В вашем приложении Angular нет способа по умолчанию ответить на это.
Возможно, вы сможете смоделировать что-то, используя onBeforeUnload() для регистрации того, что приложение было перезагружено; а затем проверьте этот журнал в процедуре инициализации вашего приложения, чтобы выполнить какое-то специальное действие.
I want to detect when page is refresh using router
Вы добавляете преобразователь высший уровень к маршрутизатору. Если у вас есть один маршрутизатор верхнего уровня, он будет разрешен только один раз, и дочерние узлы будут обрабатывать навигацию по страницам. Каждый раз, когда резолвер разрешается, он эквивалентен обновлению страницы в браузере.
const routes: Routes = [
{
path: '',
component: TopComponent,
resolve: { loaded: PageLoadedResolver },
children: [
...
]
}
];
Есть много других способов обнаружения события загрузки страницы в Angular.
Конструктор вашего AppModule
.
@NgModule({...})
export class AppModule {
public constructor() {
console.info('page loaded');
}
}
Служба, введенная в корень, которая используется хотя бы один раз.
@Injector({provideIn: 'root'})
export class MyService {
public constructor() {
console.info('page loaded');
}
}
Существует также файл main.ts
, который загружает приложение Angular.
platformBrowserDynamic().bootstrapModule(AppModule)
.then(() => console.info('page loaded'))
.catch(err => console.error(err));
По сути, везде, где есть JavaScript, который запускается один раз...
попробуй это
this.router.events
.pipe(filter((rs): rs is NavigationEnd => rs instanceof NavigationEnd))
.subscribe(event => {
if (
event.id === 1 &&
event.url === event.urlAfterRedirects
) {
..... // here your code when page is refresh
}
})
Вам нужно будет импортировать
import { filter } from 'rxjs/operators'
import { Router } from '@angular/router';
Я использовал этот код, и он работал у меня первые два раза (я могу выполнить некоторый код, когда пользователь нажимает кнопку обновления), но он внезапно перестал работать (мой упомянутый код больше не выполняется), и с тех пор я ничего не менял. Так как же это происходит?. Я использую Firefox 71.0
Я предполагаю, что вы используете import { filter } from 'rxjs/operators'
@DeadlyChambers, да import { filter } from 'rxjs/operators';
это действительно работает? потому что в моем приложении я проверяю событие unload
, поэтому я хочу знать, делает ли использование угловой маршрутизации то же самое
В компоненте .ts
import { Subscription } from 'rxjs';
export let browserRefresh = false;
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnDestroy {
subscription: Subscription;
constructor(private router: Router) {
this.subscription = router.events.subscribe((event) => {
if (event instanceof NavigationStart) {
browserRefresh = !router.navigated;
}
});
}
на нужной вам странице
import { browserRefresh } from '../app.component';
....
ngOnInit() {
this.browserRefresh = browserRefresh;
console.info('refreshed?:', browserRefresh);
}
См. рабочий пример здесь https://stackblitz.com/edit/refreshangular?file=src%2Fapp%2Fpage-a%2Fpage-a.component.ts
Нажмите на страницу A и страницу B и обновите страницу, чтобы увидеть разницу
Хороший! StackBlitz сделал ваше решение простым для понимания.
Хорошо, но я реализую как сервис, а не импорт из app.component, потому что это вызовет проблемы с производительностью в больших приложениях.
Как это должно решить? router.navigated всегда ложно. Независимо от того, вводите ли вы URL-адрес новой вкладки или обновляете ее. Также в консоли stackblitz пишет true в обоих случаях.
@char 5 Я редактирую вопрос. Вам нужно щелкнуть страницу A или B, чтобы увидеть, что она не обновляется, а затем, если вы обновите или наберете URL-адрес, будет обновлено = true
Спасибо! Я понимаю, но здесь ввод URL-адреса, т.е. запуск нового сеанса и обновление сеанса, совпадают. по крайней мере, я хотел бы знать, обновляется ли существующий сеанс. это не решение для этого. это можно сделать в большинстве браузеров, но я не нашел способ, который работает в Safari
@charm Я использую Safari. Да, ввод URL-адреса или обновление сеанса — одно и то же. Чтобы изменить страницу путем маршрутизации (нажмите кнопку Страница B), обновление не происходит. Я не понимаю, что вам нужно?
Чтобы обнаружить обновление браузера, как говорится в заголовке. Это происходит, когда у пользователя есть сеанс, например myapp:4200/pageX, и он нажимает F5 или кнопку «Обновить» в браузере. Затем он должен вернуться к myapp:4200/pageX и обнаружить, что существующий сеанс был обновлен. Мое приложение довольно сложное, и мне нужно знать. Другие браузеры предоставляют эту информацию, вызывая performance.getEntriesByType('navigation'). В Safari массив пуст.
Новейший способ в Angular 7+, теперь мы можем добавлять свойства навигации по маршруту.
Итак, если /somepage
— это страница, которую мы хотим определить, был ли обновлен браузер, мы устанавливаем свойство навигации prevPage, когда переходим на эту страницу:
this.router.navigate(['/somepage'], { state: { prevPage: this.router.url } });
Затем внутри какой-то страницы:
ngOnInit(): void {
const previousUrl = history.state.prevPage ?? null;
if (!this.previousUrl) {
console.info('page was refreshed!');
} else {
console.info('I came here from: ', previousUrl);
}
}
Примечание: Это работает, если вы хотите обнаружить обновление браузера с определенной страницы.
Если вам это нужно на всем сайте, я бы выбрал другой подход.
Не идеальное решение...!
Если вы используете sessionStorage, сеанс сохраняется, и если ваше приложение использует это sessionStorage, то это не то же самое, что закрытие и запуск, потому что sessionStorage будет сохраняться между перезагрузками. Он очищается только вручную или при закрытии окна (/ вкладки).