Meteor:带有 Iron Router 的用户配置文件页面 [英] Meteor: User Profile Page with Iron Router
问题描述
我正在努力使用位于 localhost:3000/:username
的 Iron Router 创建用户配置文件页面.个人资料页面应具有以下特征:
I'm struggling to create a user profile page, using Iron Router, which is located at localhost:3000/:username
. The profile page should have the following characteristics:
- 公共视图 - 任何人都可以查看用户的基本信息
- 私人视图 - 如果客户在登录时访问他或她自己的个人资料页面,则会显示他或她的敏感用户数据并且他们具有编辑功能
- 加载视图 - 在获取用户个人资料数据时,显示加载屏幕
- 未找到视图 - 如果在 URL 中输入了无效用户名,则返回未找到页面.
公共视图和私有视图应该存在于相同 URL 路径中.根据客户端的凭据,他们会看到一个或另一个,而无需重定向到不同的页面.未找到的页面也不应该重定向,这样用户在输入无效用户名时仍然可以在浏览器 URL 栏中看到无效的 URL.
The public view and private view should exist at the same URL path. 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.
我的 router.js 文件:
My router.js file:
this.route('profile', {
controller: 'ProfileController',
path: '/:username'
});
在 ProfileController
中,我试图拼凑以下内容:
Within ProfileController
, I'm trying to scrape together the following:
onBeforeAction
- 显示加载画面;确定用户名是否存在(也就是 URL 是否有效)- 显示未找到的视图、私人资料或公开资料
onBeforeAction
- show loading screen; determine if username exists (aka if URL is valid)- Either show not found view, private profile, or public profile
谢谢!
推荐答案
幸运的是,您正在寻找的每个特性都可以在插件中使用,因此您甚至不必深入定义自己的钩子.
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.
请注意,我正在使用
iron:router@1.0.0-pre2
,这对于跟上最新的东西很重要,目前我希望只有两个小怪癖尽快修复.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.让我们从用户配置文件发布开始,它以用户名作为参数.
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 } }); } });
让我们继续配置文件模板,这里没什么特别的,我们将用户名显示为公共数据,如果我们正在查看私人配置文件,则显示我们假设存储在
profile 中的用户真实姓名.姓名
.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
.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>
然后我们需要在全局路由器配置中为profile view定义一个路由:
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" });
请注意,
iron:router
现在要求您在共享目录中定义路由和路由控制器(通常这是项目根目录下的lib/
目录) 对客户端和服务器都可用.Note that
iron:router
now requires that you define your routes and route controllers in the shared directory (usually this is thelib/
dir at the root of your project) available to both client and server.现在是最棘手的部分,
ProfileController
定义:Now for the trickiest part, the
ProfileController
definition :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 }); } });
当
iron:router
检测到您在RouteController
中使用waitOn
时,它现在会自动添加默认的loading
钩子,负责在订阅尚未准备好时呈现loadingTemplate
.When
iron:router
detects that you're usingwaitOn
in aRouteController
it will now automatically add the defaultloading
hook which is responsible for rendering theloadingTemplate
while the subscription is not yet ready.现在我将解决我在开始回答时谈到的两个小错误.
I'll address now the two minor bugs I've talked about in the beggining of my answer.
首先,官方
iron:router
指南(你绝对应该阅读)http://eventedmind.github.io/iron-router/ 提到您应该传递给dataNotFound
插件的选项的名称是dataNotFoundTemplate
但截至 28-09-2014 这不起作用,您需要使用旧名称notFoundTemplate
,这可能会在几天内修复.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 thedataNotFound
plugin isdataNotFoundTemplate
but as of 28-09-2014 this won't work, you need to use the legacy namenotFoundTemplate
, this is likely to get fixed in a matter of days.控制器中我的
data
函数的代码也是如此:我使用了反直觉语法Router.current().params
来访问通常this.params
将是适当的常规语法时的路由参数.这是另一个尚未解决的问题.https://github.com/EventedMind/iron-router/issues/857The same goes for the code of my
data
function in the controller : I've used the counter-intuitive syntaxRouter.current().params
to access the route parameters when normallythis.params
would have been the appropriate regular syntax. This is another yet-to-be-addressed issue. https://github.com/EventedMind/iron-router/issues/857这篇关于Meteor:带有 Iron Router 的用户配置文件页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!