为什么我的共享服务没有跨组件更新?
Why is my shared service not updating across my components?
在我的 Angular2 应用程序中,我正在引导我希望在我的组件之间共享的身份验证服务 LocalStorage
:
bootstrap(AppComponent, [
ROUTER_PROVIDERS,
LocalStorage
]);
LocalStorage
定义如下:
import {JwtHelper} from 'angular2-jwt/angular2-jwt';
import { Injectable } from 'angular2/core';
@Injectable()
export class LocalStorage {
key:string = 'jwt';
jwtHelper:JwtHelper = new JwtHelper();
username:string;
constructor() {
let token = localStorage.getItem(this.key);
if (token == null) return;
if (this.jwtHelper.isTokenExpired(token)) {
localStorage.removeItem(this.key);
} else {
this.username = this.jwtHelper.decodeToken(token).username;
}
}
login(jwt:string) {
localStorage.setItem(this.key, jwt);
}
logout() {
localStorage.removeItem(this.key);
}
isLoggedIn():boolean {
return this.username != null;
}
getUsername():string {
return this.username;
}
getToken():string {
return localStorage.getItem(this.key);
}
}
但是,问题是,当我跨组件共享和更新它时,只有更新它的组件会识别更改。它被注入到组件中并像这样编辑:
constructor(private router:Router, private localStorage:LocalStorage) {
...
}
logout(event) {
event.preventDefault();
this.localStorage.logout();
this.router.navigateByUrl(RoutingPaths.home.path);
}
为什么似乎跨组件创建了此服务的多个实例?谢谢。
编辑 一个组件模板绑定的例子是:
组件:
import {Component} from 'angular2/core';
import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {RoutingPaths} from './routing-paths';
import {LoggedInOutlet} from './logged-in-outlet';
import {LocalStorage} from './local-storage'
@Component({
selector: 'my-app',
templateUrl: 'app/app.template.html',
directives: [LoggedInOutlet, ROUTER_DIRECTIVES]
})
export class AppComponent {
registerName:string;
constructor(private router:Router, private localStorage:LocalStorage) {
this.registerName = RoutingPaths.register.name;
}
logout(event) {
event.preventDefault();
this.localStorage.logout();
this.router.navigateByUrl(RoutingPaths.home.path);
}
}
模板:
<a *ngIf="!localStorage.isLoggedIn()" [routerLink]="[registerName]">Register</a>
最终编辑
嗯,这很尴尬,在服务中实际编辑用户名后它现在可以工作了:
login(jwt:string) {
localStorage.setItem(this.key, jwt);
this.username = this.jwtHelper.decodeToken(jwt).username; // here
}
logout() {
localStorage.removeItem(this.key);
this.username = null; // here
}
抱歉浪费大家的时间。再次感谢。
The problem is, however, when I share and update it across components only the component that updates it recognizes the changes
这是因为 angular 2 个组件模型是一棵树:
因此只有 发生变化的组件及其子组件 被重新渲染。对于跨组件使用的单例 containing 状态,您需要 redux
之类的东西:https://medium.com/google-developer-experts/angular-2-introduction-to-redux-1cf18af27e6e#.yk11zfcwz
我忘了实际修改服务本身的用户名:
login(jwt:string) {
localStorage.setItem(this.key, jwt);
this.username = this.jwtHelper.decodeToken(jwt).username; // here
}
logout() {
localStorage.removeItem(this.key);
this.username = null; // here
}
这是因为您在代码中的某处将 LocalStorage 指定为提供程序。
检查您的任何组件是否包含:
@Component({
providers: [LocalStorage]
})
这给出了一个注入器指令,用于为该组件和所有子组件创建一个新实例,如果子组件本身没有提供 LocalStorage。
在我的 Angular2 应用程序中,我正在引导我希望在我的组件之间共享的身份验证服务 LocalStorage
:
bootstrap(AppComponent, [
ROUTER_PROVIDERS,
LocalStorage
]);
LocalStorage
定义如下:
import {JwtHelper} from 'angular2-jwt/angular2-jwt';
import { Injectable } from 'angular2/core';
@Injectable()
export class LocalStorage {
key:string = 'jwt';
jwtHelper:JwtHelper = new JwtHelper();
username:string;
constructor() {
let token = localStorage.getItem(this.key);
if (token == null) return;
if (this.jwtHelper.isTokenExpired(token)) {
localStorage.removeItem(this.key);
} else {
this.username = this.jwtHelper.decodeToken(token).username;
}
}
login(jwt:string) {
localStorage.setItem(this.key, jwt);
}
logout() {
localStorage.removeItem(this.key);
}
isLoggedIn():boolean {
return this.username != null;
}
getUsername():string {
return this.username;
}
getToken():string {
return localStorage.getItem(this.key);
}
}
但是,问题是,当我跨组件共享和更新它时,只有更新它的组件会识别更改。它被注入到组件中并像这样编辑:
constructor(private router:Router, private localStorage:LocalStorage) {
...
}
logout(event) {
event.preventDefault();
this.localStorage.logout();
this.router.navigateByUrl(RoutingPaths.home.path);
}
为什么似乎跨组件创建了此服务的多个实例?谢谢。
编辑 一个组件模板绑定的例子是:
组件:
import {Component} from 'angular2/core';
import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {RoutingPaths} from './routing-paths';
import {LoggedInOutlet} from './logged-in-outlet';
import {LocalStorage} from './local-storage'
@Component({
selector: 'my-app',
templateUrl: 'app/app.template.html',
directives: [LoggedInOutlet, ROUTER_DIRECTIVES]
})
export class AppComponent {
registerName:string;
constructor(private router:Router, private localStorage:LocalStorage) {
this.registerName = RoutingPaths.register.name;
}
logout(event) {
event.preventDefault();
this.localStorage.logout();
this.router.navigateByUrl(RoutingPaths.home.path);
}
}
模板:
<a *ngIf="!localStorage.isLoggedIn()" [routerLink]="[registerName]">Register</a>
最终编辑
嗯,这很尴尬,在服务中实际编辑用户名后它现在可以工作了:
login(jwt:string) {
localStorage.setItem(this.key, jwt);
this.username = this.jwtHelper.decodeToken(jwt).username; // here
}
logout() {
localStorage.removeItem(this.key);
this.username = null; // here
}
抱歉浪费大家的时间。再次感谢。
The problem is, however, when I share and update it across components only the component that updates it recognizes the changes
这是因为 angular 2 个组件模型是一棵树:
因此只有 发生变化的组件及其子组件 被重新渲染。对于跨组件使用的单例 containing 状态,您需要 redux
之类的东西:https://medium.com/google-developer-experts/angular-2-introduction-to-redux-1cf18af27e6e#.yk11zfcwz
我忘了实际修改服务本身的用户名:
login(jwt:string) {
localStorage.setItem(this.key, jwt);
this.username = this.jwtHelper.decodeToken(jwt).username; // here
}
logout() {
localStorage.removeItem(this.key);
this.username = null; // here
}
这是因为您在代码中的某处将 LocalStorage 指定为提供程序。
检查您的任何组件是否包含:
@Component({
providers: [LocalStorage]
})
这给出了一个注入器指令,用于为该组件和所有子组件创建一个新实例,如果子组件本身没有提供 LocalStorage。