У меня есть приложение курсов на английском и французском языках.Я хочу сделать заголовок для выпадающего списка языков в другом компоненте, который появится на всех страницах программы.Когда пользователь меняет язык в заголовке, я хочу, чтобы это происходило:
- Интерфейс вызывает бэкэнд и меняет предпочтения языка для пользователя, поэтому в следующий раз, когда он войдет, он увидит курсына языке, который он выбрал
- , что независимо от того, где, маршрут изменится на страницу со списком курсов и загрузит курсы с обновленными настройками.
Пока это только работаесли я обновлю страницу и не сразу.Когда я писал языковую кнопку в каждом компоненте, он работал.
РЕДАКТИРОВАТЬ: он работает на всех страницах, кроме списка курсов, возможно, потому что мы уже внутри этого компонента, поэтому мы нене вызывать функцию getCoursesByLanguage (когда мы находимся на других компонентах, я использую router.navigate к компоненту списка курсов, который запускает getCoursesByLanguage).Как заставить это работать на странице списка курсов?
это соответствующий код:
app.component.html
<div class='container-fluid' id='main'>
<lg-header></lg-header>
<router-outlet></router-outlet>
</div>
header.component.html
<div style="float:right; padding-right:30px">
<button id="button-logout" mat-button (click)="toggleLanguage()">
<img width="27" height="17" style="margin-right: 10px;" src="./assets/images/{{flag}}_Flag.png"/>
<span>{{languageName}}</span>
</button>
</div>
header.component.ts
import { Component, OnInit, Pipe, PipeTransform } from '@angular/core';
import { ActivatedRoute, Router, Routes } from '@angular/router';
import { LocalStorage } from '@ngx-pwa/local-storage';
import { IUser, IUserCourses } from '../users/user';
import { UserProgressService } from '../users/user-progress.service';
@Component({
selector: 'lg-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.sass']
})
export class HeaderComponent implements OnInit {
// variables for laungage
language: number;
languageName: string;
flag: string;
constructor(private route: ActivatedRoute,
private router: Router,
private userProgressService: UserProgressService) {
userProgressService.connectUser();
this.getUpdatedLanguageAndFlag();
}
// get from service updated data from backend and localStorage
getUpdatedLanguageAndFlag() {
this.language = this.userProgressService.getLanguage();
this.flag = this.userProgressService.getFlag();
this.languageName = this.userProgressService.getLanguageName();
}
ngOnInit() { }
// change laungage
toggleLanguage(){
this.userProgressService.changeAppLanguage();
this.getUpdatedLanguageAndFlag();
if (this.router.url == '/courses') {
// I need to trigger here getCourseListByLanguage in course-list from here
}
else
this.router.navigate(["/courses"]);
}
}
user-progress.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, groupBy } from 'rxjs/operators';
import { LocalStorage } from '@ngx-pwa/local-storage';
import { UserService } from './user.service';
import { IUser, IUserCourses } from './user';
@Injectable({
providedIn: 'root'
})
export class UserProgressService {
private user: IUser;
private errorMessage: string;
private language: number;
private flag: string;
private languageName: string;
constructor(private userService: UserService) { }
// get user from local store
connectUser() {
this.user = JSON.parse(localStorage.getItem('user'));
this.language =+ localStorage.getItem('language');
this.flag = localStorage.getItem('flag');
this.languageName = localStorage.getItem('languageName');
}
getUserName() {
return this.user.name;
}
getLanguage() {
return this.language;
}
getLanguageName() {
return this.languageName;
}
getFlag() {
return this.flag;
}
// determine flag and language name depends on language value
setFlagLanName() {
if (this.language == 0) {
this.flag = "UK";
this.languageName = "English";
}
else {
this.flag = "FR";
this.languageName = "French";
}
localStorage.setItem('languageName', this.languageName);
localStorage.setItem('flag', this.flag);
}
// manage toggle action
changeAppLanguage() {
if ( this.language == 0 )
this.language = 1;
else
this.language = 0;
this.setFlagLanName();
this.updateBackendLanguage(this.language);
}
// update language in backend
updateBackendLanguage(lan: number) {
this.userService.updateLanguage(this.user.id, lan).subscribe(
() => { this.getUserFromBackend(); },
error => this.errorMessage = <any>error
);
}
// update user after changes - call the backend again for GET
getUserFromBackend() {
this.userService.getUser(this.user.id).subscribe(
user => {
this.user = user;
this.language = user.language;
localStorage.setItem('user', JSON.stringify(this.user));
localStorage.setItem('language', this.user.language.toString());
},
error => this.errorMessage = <any>error
);
}
}
user.service.ts
import { environment } from '../../environments/environment';
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders, HttpParams } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs';
import { Observable, throwError } from 'rxjs';
import { catchError, groupBy, tap } from 'rxjs/operators';
import { IUser, IUserCourses } from './user';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
@Injectable()
export class UserService {
private url = environment.educationBE_url+'/users';
constructor(private http: HttpClient) { }
// Get Single user by id. will 404 if id not found
getUser(id: number): Observable<IUser> {
const detailUrl = `${this.url}/${id}` + '.json';
return this.http.get<IUser>(detailUrl)
.pipe(catchError(this.handleError));
}
// update user preference for language view
updateLanguage(user_id: number, language: number) {
const userUrl = `${this.url}/${user_id}` + '.json';
let body = JSON.stringify({language: language});
return this.http.patch(userUrl, body, httpOptions)
.pipe(
tap(_ => console.log(`updated user ${user_id} with this entry: ${language}`)),
catchError(this.handleError)
);
}
// // Handle Any Kind of Errors
private handleError(error: HttpErrorResponse) {
// A client-side or network error occured. Handle it accordingly.
if (error.error instanceof ErrorEvent) {
console.error(`Error: ${error.error.message}`);
}
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong.
else {
console.error(`Error Code: ${error.status}\nMessage: ${error.message}`);
}
// return an Observable with a user-facing error error message
return throwError(
'Something bad happend; please try again later.');
}
}
course-list.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, Routes } from '@angular/router';
import { ICourse } from '../course';
import { CourseService } from '../course.service';
import { UserProgressService } from '../../users/user-progress.service';
@Component({
selector: 'lg-course-list',
templateUrl: './course-list.component.html',
styleUrls: ['./course-list.component.sass']
})
export class CourseListComponent implements OnInit {
courses: ICourse[] = [];
errorMessage: string;
// variables for laungage
language: number;
languageName: string;
flag: string;
// the courses we display in html file
coursesByLanguage: ICourse[] = [];
constructor(private courseService: CourseService,
private userProgressService: UserProgressService,
private route: ActivatedRoute,
private router: Router) {
userProgressService.connectUser();
this.getUpdatedLanguageAndFlag();
}
ngOnInit() {
this.getCourseList();
}
getUpdatedLanguageAndFlag() {
this.language = this.userProgressService.getLanguage();
this.flag = this.userProgressService.getFlag();
this.languageName = this.userProgressService.getLanguageName();
}
// Get list of courses from service
getCourseList() {
this.courseService.getCourses()
.subscribe(
courses => {
this.courses = courses;
this.getCourseListByLanguage();
},
errorMessage => this.errorMessage = <any>Error
);
}
// get from courses only the relavent ones
getCourseListByLanguage() {
this.getUpdatedLanguageAndFlag();
this.coursesByLanguage = this.courses.filter( course => course.language == this.language);
}
// change laungage
toggleLanguage(){
this.userProgressService.changeAppLanguage();
this.getCourseListByLanguage();
}
}