[英]Meteor: User Profile Page with Iron Router
I'm struggling to create a user profile page, using Iron Router, which is located at localhost:3000/:username
. 我正在努力创建一个用户配置文件页面,使用Iron Router,它位于localhost:3000/:username
。 The profile page should have the following characteristics: 配置文件页面应具有以下特征:
The public view and private view should exist at the same URL path. 公共视图和私有视图应存在于同一 URL路径中。 Depending on the client's credentials, they see one or the other without a redirect to a different page. 根据客户端的凭据,他们会看到一个或另一个没有重定向到其他页面。 The not found page should also not redirect, this way the user can still see the invalid URL in the browser URL bar if the enter an invalid username. 未找到的页面也不应该重定向,这样如果输入无效的用户名,用户仍然可以在浏览器URL栏中看到无效的URL。
My router.js file: 我的router.js文件:
this.route('profile', {
controller: 'ProfileController',
path: '/:username'
});
Within ProfileController
, I'm trying to scrape together the following: 在ProfileController
,我试图凑合以下内容:
onBeforeAction
- show loading screen; onBeforeAction
- 显示加载屏幕; determine if username exists (aka if URL is valid) 确定用户名是否存在(即URL是否有效)
waitOn
- wait for username
's data to be retrieved before removing loading screen waitOn
- 在删除加载屏幕之前等待检索username
的数据 onAfterAction
- remove loading screen onAfterAction
- 删除加载屏幕 Thanks! 谢谢!
Luckyly, every characteristics you are looking for are available as baked in plugins so you won't even have to dive in defining your own hooks. 幸运的是,您正在寻找的每个特征都可以在插件中找到,因此您甚至不必潜入定义自己的挂钩。
Notice that I'm using iron:router@1.0.0-pre2
, this is important to keep up with the latest stuff, there are just two minor quirks at the moment that I hope will get fixed soon. 请注意,我正在使用iron:router@1.0.0-pre2
,这对于跟上最新的东西非常重要,目前只有两个小怪癖,我希望很快能得到修复。
Let's start with the user profile publication, which take the username as argument. 让我们从用户配置文件发布开始,它将用户名作为参数。
server/collections/users.js
Meteor.publish("userProfile",function(username){
// simulate network latency by sleeping 2s
Meteor._sleepForMs(2000);
// try to find the user by username
var user=Meteor.users.findOne({
username:username
});
// if we can't find it, mark the subscription as ready and quit
if(!user){
this.ready();
return;
}
// if the user we want to display the profile is the currently logged in user...
if(this.userId==user._id){
// then we return the corresponding full document via a cursor
return Meteor.users.find(this.userId);
}
else{
// if we are viewing only the public part, strip the "profile"
// property from the fetched document, you might want to
// set only a nested property of the profile as private
// instead of the whole property
return Meteor.users.find(user._id,{
fields:{
"profile":0
}
});
}
});
Let's continue with the profile template, nothing too fancy here, we'll display the username as public data, and if we are viewing the private profile, display the user real name that we assume is stored in profile.name
. 让我们继续使用配置文件模板,这里没什么特别的,我们将用户名显示为公共数据,如果我们正在查看私有配置文件,则显示我们假设存储在profile.name
的用户真实姓名。
client/views/profile/profile.html
<template name="profile">
Username: {{username}}<br>
{{! with acts as an if : the following part won't be displayed
if the user document has no profile property}}
{{#with profile}}
Profile name : {{name}}
{{/with}}
</template>
Then we need to define a route for the profile view in the global router configuration : 然后我们需要在全局路由器配置中为配置文件视图定义路由:
lib/router.js
// define the (usually global) loading template
Router.configure({
loadingTemplate:"loading"
});
// add the dataNotFound plugin, which is responsible for
// rendering the dataNotFound template if your RouteController
// data function returns a falsy value
Router.plugin("dataNotFound",{
notFoundTemplate: "dataNotFound"
});
Router.route("/profile/:username",{
name:"profile",
controller:"ProfileController"
});
Note that iron:router
now requires that you define your routes and route controllers in the shared directory (usually this is the lib/
dir at the root of your project) available to both client and server. 请注意, iron:router
现在要求您在客户端和服务器都可用的共享目录(通常是项目根目录中的lib/
dir)中定义路由和路由控制器。
Now for the trickiest part, the ProfileController
definition : 现在到了最棘手的部分,该ProfileController
定义:
lib/controllers/profile.js
ProfileController=RouteController.extend({
template:"profile",
waitOn:function(){
return Meteor.subscribe("userProfile",this.params.username);
},
data:function(){
var username=Router.current().params.username;
return Meteor.users.findOne({
username:username
});
}
});
When iron:router
detects that you're using waitOn
in a RouteController
it will now automatically add the default loading
hook which is responsible for rendering the loadingTemplate
while the subscription is not yet ready. 当iron:router
检测到您使用waitOn
在RouteController
它现在会自动添加默认loading
钩负责渲染loadingTemplate
而认购还没有准备好。
I'll address now the two minor bugs I've talked about in the beggining of my answer. 我现在要解决我在回答问题时谈到的两个小错误。
First, the official iron:router
guide (which you should definitely read) http://eventedmind.github.io/iron-router/ mentions that the name of the option you should pass to the dataNotFound
plugin is dataNotFoundTemplate
but as of 28-09-2014 this won't work, you need to use the legacy name notFoundTemplate
, this is likely to get fixed in a matter of days. 首先,官方iron:router
指南(你一定要阅读) http://eventedmind.github.io/iron-router/提到你应该传递给dataNotFound
插件的选项的名称是dataNotFoundTemplate
但是从28- 09-2014这不起作用,你需要使用遗留名称notFoundTemplate
,这可能会在几天内得到修复。
The same goes for the code of my data
function in the controller : I've used the counter-intuitive syntax Router.current().params
to access the route parameters when normally this.params
would have been the appropriate regular syntax. 对于控制器中我的data
函数的代码也是如此:我使用反直觉语法Router.current().params
来访问路由参数,通常this.params
是适当的常规语法。 This is another yet-to-be-addressed issue. 这是另一个尚未解决的问题。 https://github.com/EventedMind/iron-router/issues/857 https://github.com/EventedMind/iron-router/issues/857
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.