我正在构建使用模型,服务和自定义元素的Aurelia框架的相当先进的应用程序。对象的引用以某种方式丢失
我有一个用户模型包含用户名,电子邮件等以及bool isLoggedIn。
我有一个存储用户在localStorage的用户服务,让您更新用户数据等等等等
我终于有使用用户服务的一些自定义元素,以获取当前用户,并显示UI这取决于用户是否登录。
我面临的问题是,在使用用户服务提取用户后,从我的一个自定义元素(存储在用户服务中)更新用户模型后,另一个自定义元素对所述用户的引用型号不会更新。
我试着在JSFiddle中复制这个问题(在普通的JS中 - 我正在写这个在ES6中),但没有这样做,在小提琴中的所有工作正常。
这里有很多代码,但我想听听您的意见,我可能会为此发生什么错误?
这里是我有什么要点:
user.model.js
export class User {
username = '';
isLoggedIn = false;
constructor (data) {
Object.assign(this, data);
}
}
user.service.js
import { User } from 'user.model';
export class UserService {
constructor() {
this.user = null;
}
getUser() {
// User is cached
if (this.user) {
return Promise.resolve(this.user);
}
// Check if we have localStorage
var user = window.localStorage.getItem('user');
if (user) {
this.user = new User(JSON.parse(user));
return Promise.resolve(this.user);
}
// No user - create new
this.user = new User();
return Promise.resolve(this.user);
}
saveUser() {
this.getUser().then(() => {
window.localStorage.setItem('user', JSON.stringify(this.user));
});
}
updateUser (user) {
this.getUser().then(() => {
Object.assign(this.user, user);
this.saveUser();
});
}
login() {
this.updateUser({
isLoggedIn: true
});
return Promise.resolve(true);
}
}
定制element.js
import { inject } from 'aurelia-framework';
import { UserService } from 'user.service';
@inject (UserService)
export class CustomElement {
constructor (userService) {
this.userService = userService;
}
attached() {
this.userService.getUser().then(user => {
this.user = user;
console.log('Fetched user:');
console.dir(this.user);
console.log('Same?');
console.dir(this.user === user); // this is true
});
// At some point another custom element fires the UserService.login() method
// Here we check that our reference to the user also updates
setInterval(() => {
console.log('Is user logged in?');
console.dir(this.user.isLoggedIn); // This is always false - even after UserService.login() has been called and UserService.user is updated (if I console.dir this.user inside UserService it is indeed updated)
// Grab a new version of UserService.user
this.userService.getUser().then(user => {
console.log('Fetched new user, is new user and our user same?');
console.dir(this.user === user); // false :/ the new user fetched here actually has isLoggedIn === true but our this.user does not...
});
}, 2000);
}
}
正如在评论中指出,在一个点其他自定义元素运行UserService.login()
从而改变UserService.user.isLoggedIn
到true
(这体现在UserService
如果我console.dir
其this.user
),但其他CustomElement
的this.user
不不更新。
顺便说一句:Promise.resolve()
在UserService.getUser()
的原因是,将来会有服务器调用。
Tbh对于这种类型的JS编程,来自jQuery世界的更多新东西,即使我基本上爱上了Aurelia这样的东西,仍然让我非常困惑,所以希望在这里有一些见解: )
嗯,我不知道我遵循...你做的不同是,而不是'UserStore.user'是一个'新的用户()'它实际上是用户模型?这不妨碍我在别处使用用户模型吗?另外,你会建议有一个单独的'AuthService'?我已经基本上完成了整个系统,而没有太多关于如何构建这种结构的东西。如果你有一个关于JS的OOP认证/用户处理的教程或文章的链接,我很乐意阅读它。 – powerbuoy
你可以结合UserStore和AuthStore,没有硬性规则,做你最适合的方法。我试图展示的主要内容是取决于用户的东西不需要异步API。他们可以通过依赖它来访问用户实例(使用'@ inject')。对用户执行操作(将其从匿名状态移动到登录状态)可能是异步的(AuthService是异步的,但UserStore不是)。 –
好的,我将不得不试验一下这个,看看我是否理解了一切。但是,你的代码的主要区别在于你将'UserService.user'设置为实际的'User'类而不是'User'类的实例(使用'new User()')?这就是为什么当我稍后在我的自定义元素中注入相同的'User'类时,它们将会是相同的吗? – powerbuoy