Я хочу, чтобы, если сеть недоступна и пользователь пытается перейти на следующую страницу, компонент был бы там.
Но если сети нет и пользователь не предпринимает никаких действий, значит не переходит на вторую страницу. тогда не должно быть страницы с потерей соединения. Пользователь должен оставаться на текущей странице.
Для этого я реализовал защиту canActivate в виде следующего кода:
@Injectable({
providedIn: 'root'
})
export class NetworkGuard implements CanActivate {
constructor(private router: Router, private network: NetworkService) {
}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (window.navigator.onLine) {
return true;
} else {
if (!this.isConnectionLostComponent()) {
this.router.navigate(['/connection-lost'], {skipLocationChange: true});
}
return false;
}
}
private isConnectionLostComponent() {
// check whether connection lost component is added on not
return this.network.isActive;
}
}
Работает нормально, кроме одного условия.
То есть, если я нажму назад или вперед из браузера, его URL-адрес обновления ConnectionLost на Адресная строка
Как я могу решить эту проблему? Можно посмотреть образец Здесь
шаги для создания проблемы:
Я просто не хочу обновлять URL-адрес с помощью «/ соединение-потеряно», для этого я добавил параметр connection-lost к методу skipLocationChange: true в router.navigate, но все равно это не работает.
@trichetriche Я могу проверить последний посещенный URL-адрес, но как я могу запретить пользователю вернуться, пока он / она не будет в сети, и я добавил условие аналогичного типа в метод isConnectionLostComponent (), пожалуйста, проверьте мой обновленный вопрос.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я не знаю, правильное это решение или нет, но то, что я сделал в своем проекте, выглядит следующим образом.
app.component.ts
constructor(){
this.onlineOffline = Observable.merge(of(navigator.onLine),
fromEvent(window, 'online').pipe(map(() => true)),
fromEvent(window, 'offline').pipe(map(() => false))
);
}
app.component.html
<ng-container *ngIf = "onlineOffline | async; then thenTemplate; else elseTemplate"></ng-container>
<ng-template #thenTemplate>
<router-outlet></router-outlet>
</ng-template>
<ng-template #elseTemplate>
<app-no-network></app-no-network>
</ng-template>
Дайте мне знать, работает ли он так, как вам нужно, или нет.
это хороший ответ, и я пробовал его раньше, но на этот раз я хочу показать компонент «приложение без сети» в навигации. не так быстро, как пользователь отключается от сети.
Кстати, какая польза от этого? Я просто хочу знать. @RaviSevta
Пользователь может видеть содержимое текущей страницы, если нет сети. действовать — дело вторичное. @ АлокеТ
Таким образом, вы можете сделать прозрачный оверлей и активировать его, когда нет сети, чтобы пользователь мог только видеть контент, но не мог ничего сделать. также добавьте <app-no-network> свойство с именем show, которое будет отображать небольшие изменения на странице, как YouTube в своем приложении для Android.
но я должен показать пользовательский интерфейс разрыва соединения без интернета.
Да, это то, что я хочу.
Давайте продолжить обсуждение в чате.
После небольшого поиска и с помощью ответа @AlokeT. Я получил решение этой проблемы.
Предложение @AlokeT показывает страницу потери соединения, как только пользователь потерял свою сеть. но мое требование состоит в том, чтобы показать эту страницу потери соединения, когда он/она пытается перейти на другую страницу.
И в этом ответе я просто добавил недостающую часть.
Для этого я просто обновляю этот флаг isNetworkStopped из Guard, и потому что каждый Guard CanActivate выполняется до начала навигации. Таким образом, компонент потери соединения будет отображаться, когда пользователь меняет путь.
Есть код NetworkService, который я использую в NetworkGuard,
@Injectable({providedIn: 'root'})
export class NetworkService {
online: boolean;
isNetworkStopped = false;
constructor() {
this.online = window.navigator.onLine;
fromEvent(window, 'online').subscribe(e => {
this.online = true;
});
fromEvent(window, 'offline').subscribe(e => {
this.online = false;
});
}
}
Здесь в приведенном выше коде я просто добавил флаг isNetworkStopped. И обновил этот флаг с NetworkGuard, что означает, что пользователь пытается перейти на следующую страницу и не находит сети.
А также убрал навигацию из NetworkGuard.
Смотрите мой ниже, обновленный код NetoworkGuard
@Injectable({providedIn: 'root'})
export class NetworkGuard implements CanActivate {
constructor(private network: NetworkService) {
}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (this.network.online) {
return true;
}
this.network.isNetworkStopped = true;
return false;
}
}
И на основе этого флага мне удалось показать компонент ConnectionLost.
Для этого ConnectionLostкомпонент добавляется по условию на основе шаблона корневого компонента.
app.component.html
<router-outlet *ngIf = "!networkService.isNetworkStopped"></router-outlet>
<app-connection *ngIf = "networkService.isNetworkStopped"></app-connection>
И из компонента ConnectionLost, если пользователь нажимает кнопку перезагрузки. Проверив сетевое соединение, я обновил флаг isNetworkStoppedNetworkService.
Поскольку networkService уже имеет свойство «онлайн», почему ему все еще нужен флаг isNetworkStopped?
Да, @peanut, это правда, но поскольку пользователь переходит к другому компоненту, я меняю этот флаг (isNetworkStopped). чтобы пользователь мог видеть компонент потери соединения при изменении маршрута, а не сразу после потери соединения. Это мое основное требование.
Вы можете сохранить последний посещенный URL-адрес, и если пользователи вернутся к нему, то предотвратить ваше условие? Вы ничего не можете сделать, так как браузеры запрещают вам знать, нажал ли пользователь кнопку «Назад».