Meteor:带有 Iron Router 的用户配置文件页面 [英] Meteor: User Profile Page with Iron Router

查看:26
本文介绍了Meteor:带有 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 the lib/ 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 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.

      首先,官方 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 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.

      控制器中我的 data 函数的代码也是如此:我使用了反直觉语法 Router.current().params 来访问通常 this.params 将是适当的常规语法时的路由参数.这是另一个尚未解决的问题.https://github.com/EventedMind/iron-router/issues/857

      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

      这篇关于Meteor:带有 Iron Router 的用户配置文件页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆