简体   繁体   English

Meteor:使用Iron Router的用户配置文件页面

[英]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: 配置文件页面应具有以下特征:

  • Public view - anyone can see basic information about the user 公共视图 - 任何人都可以看到有关用户的基本信息
  • Private view - if the client visits his or her own profile page while signed-in, his or her sensitive user data is shown and they have edit capabilities 私人视图 - 如果客户在登录时访问他或她自己的个人资料页面,则会显示他或她的敏感用户数据,并且他们具有编辑功能
  • Loading view - while the user profile data is being fetched, show a loading screen 加载视图 - 在提取用户配置文件数据时,显示加载屏幕
  • Not found view - if invalid username is entered into the URL, return a not-found page. 找不到视图 - 如果在URL中输入了无效的用户名,则返回未找到的页面。

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是否有效)
    • Either show not found view, private profile, or public profile 显示未找到的视图,私人个人资料或公开个人资料
  • 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检测到您使用waitOnRouteController它现在会自动添加默认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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM