Javascript Ember.js:使当前用户全局可访问
我正在编写一个使用emberfire和Tori进行身份验证的ember应用程序(使用ember 2.3.0)。用户登录后,他们的uid在ToriJavascript Ember.js:使当前用户全局可访问,javascript,ember.js,emberfire,Javascript,Ember.js,Emberfire,我正在编写一个使用emberfire和Tori进行身份验证的ember应用程序(使用ember 2.3.0)。用户登录后,他们的uid在Tori会话对象中对我可用。我还有一个用户模型,希望在我的模板、路线等中访问与当前用户相关的其他数据 我可以通过执行以下操作,在一条路线上实现这一点: let uid = this.get('session').get('uid'); this.store.findRecord('user', uid).then(user => { console.l
会话
对象中对我可用。我还有一个用户
模型,希望在我的模板、路线等中访问与当前用户相关的其他数据
我可以通过执行以下操作,在一条路线上实现这一点:
let uid = this.get('session').get('uid');
this.store.findRecord('user', uid).then(user => {
console.log(user.get('firstName'));
});
但希望避免必须为需要访问它的每个路由/控制器写入此
有谁能建议最好的方法吗?使用服务的最佳方式是什么?如果是这样,如何确保在会话对象可用后执行服务中的代码
更新
我设法让我的应用程序使用以下解决方案:
创建使用firebase登录用户的方法
我创建了一个mixin来处理登录行为。然后在登录页面和注册页面上都使用此选项
// Mixin to handle logging in
import Ember from 'ember';
export default Ember.Mixin.create({
user: Ember.inject.service(),
email: null,
errorMsg: null,
logInUser(email, password) {
// logout existing user if any and then login new user
this.get('session').close()
.then(() => {
// if already a user logged in
this.firebaseLogin(email, password);
})
.catch(() => {
// if no user logged in
this.firebaseLogin(email, password);
});
},
firebaseLogin(email, password) {
this.get("session").open("firebase", {
provider: 'password',
email: email,
password: password
})
.then((data) => {
// If successful, fetch the user and transition to home page
console.log("Successfully logged in as ", data);
this.get('user').loadCurrentUser().then(() => {
this.transitionToRoute('index');
});
})
.catch(error => {
this.set('errorMsg', error);
});
},
});
创建用户
服务
这用于将用户
模型与身份验证用户关联
app/services/user.js
import Ember from 'ember';
export default Ember.Service.extend({
store: Ember.inject.service(),
session: Ember.inject.service(),
currentUser: null,
loadCurrentUser() {
return new Ember.RSVP.Promise((resolve, reject) => {
const uid = this.get('session').get('uid');
if (!Ember.isEmpty(uid)) {
return this.get('store').find('user', uid).then((user) => {
this.set('currentUser', user);
resolve();
}, reject);
} else {
this.set('currentUser', null);
resolve();
}
});
}
});
import Ember from 'ember';
export default Ember.Route.extend({
user: Ember.inject.service(),
beforeModel() {
return this.get("session").fetch()
.then(() => {
// Session retrieved successfully
console.log('session retrieved');
return this.get('user').loadCurrentUser();
})
.catch(() => {
// Session could not be retrieved
this.transitionTo('login');
});
}
});
将用户
服务注入应用程序路由
每当加载应用程序时(例如,当用户刷新页面时),就会调用应用程序路由。因此,正如@Deovandski在他的回答中提到的,您需要将其注入到应用程序路由中,以便用户帐户在全球范围内可用
const { service } = Ember.inject;
export default Ember.Route.extend(ApplicationRouteMixin, {
session: service('session'),
sessionAccount: service('session-account'),
beforeModel() {
return this.get('sessionAccount').loadCurrentUser();
}
});
app/routes/application.js
import Ember from 'ember';
export default Ember.Service.extend({
store: Ember.inject.service(),
session: Ember.inject.service(),
currentUser: null,
loadCurrentUser() {
return new Ember.RSVP.Promise((resolve, reject) => {
const uid = this.get('session').get('uid');
if (!Ember.isEmpty(uid)) {
return this.get('store').find('user', uid).then((user) => {
this.set('currentUser', user);
resolve();
}, reject);
} else {
this.set('currentUser', null);
resolve();
}
});
}
});
import Ember from 'ember';
export default Ember.Route.extend({
user: Ember.inject.service(),
beforeModel() {
return this.get("session").fetch()
.then(() => {
// Session retrieved successfully
console.log('session retrieved');
return this.get('user').loadCurrentUser();
})
.catch(() => {
// Session could not be retrieved
this.transitionTo('login');
});
}
});
将用户
服务注入任何需要的地方
然后,您可以通过以下方式访问当前用户:
user: Ember.inject.service()
...
let currentUser = this.get('user').get('currentUser');
正如在评论中提到的,最好的选择是使用服务。我正在为我的会话使用,这是我实现自己的自定义会话的方式,该会话全局保存登录用户:
服务/会话帐户.js
import Ember from 'ember';
const { inject: { service }, RSVP } = Ember;
export default Ember.Service.extend({
session: service('session'),
store: service(),
loadCurrentUser() {
return new RSVP.Promise((resolve, reject) => {
const uid = this.get('session.data.authenticated.uid');
if (!Ember.isEmpty(userId)) {
return this.get('store').find('user', uid).then((user) => {
this.set('user', user);
resolve();
}, reject);
} else {
resolve();
}
});
}
});
将服务注入应用程序路由
您需要将其注入应用程序路由,以便用户帐户在全局可用
const { service } = Ember.inject;
export default Ember.Route.extend(ApplicationRouteMixin, {
session: service('session'),
sessionAccount: service('session-account'),
beforeModel() {
return this.get('sessionAccount').loadCurrentUser();
}
});
将服务注入任何其他路由/控制器的示例
本例使用会话帐户将当前登录用户与正在检索的模型进行比较。其目的是仅允许拥有配置文件信息的用户编辑配置文件信息
import Ember from 'ember';
const { service } = Ember.inject;
export default Ember.Route.extend ({
session: service('session'),
sessionAccount: service('session-account'),
model: function() {
return Ember.Object.create ({
user: this.modelFor('user'),
users: this.store.findAll('user')
});
},
afterModel(model, transition) {
if (model.user.get('id') === this.get('sessionAccount.user.id')) {
// Allow Editing
}
else{
this.transitionTo('index');
}
}
});
使用服务是一种方式。我建议您尝试实现它,然后用您最终拥有的代码更新您的问题。谢谢。我最终做了一些非常类似的事情,但经过修改后与Firebase一起工作。我在一个服务中创建了一个
loadCurrentUser
方法,用户登录和应用程序路由时都会调用该方法。很高兴您的实现成功了!另外,我建议编辑我的答案,或者在你的问题中添加一个带有Firebase修改的更新部分,因为emberfire是其中一个标记。@Ross你能分享你修改这个答案的代码吗?我正在用Emberfire构建一个Ember应用程序,我遇到了与您相同的问题。@NickEmmons请参阅我对上面原始问题的编辑。希望有帮助