Meteor: User Profile Page with Iron Router

扶醉桌前 提交于 2019-11-28 07:46:11

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.

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.

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.

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
        });
    }
});

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.

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.

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. This is another yet-to-be-addressed issue. https://github.com/EventedMind/iron-router/issues/857

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!