javascript meteor iron-router

javascript - Meteor: Página de perfil de usuario con Iron Router



iron-router (1)

Estoy luchando para crear una página de perfil de usuario, utilizando Iron Router, que se encuentra en localhost:3000/:username . La página de perfil debe tener las siguientes características:

  • Vista pública: cualquiera puede ver información básica sobre el usuario
  • Vista privada: si el cliente visita su propia página de perfil mientras está conectado, se muestran sus datos de usuario confidenciales y tienen capacidades de edición.
  • Vista de carga: mientras se recuperan los datos del perfil de usuario, muestra una pantalla de carga
  • Vista no encontrada: si se ingresa un nombre de usuario no válido en la URL, devuelve una página no encontrada.

La vista pública y la vista privada deberían existir en la misma ruta de URL. Dependiendo de las credenciales del cliente, ven uno u otro sin una redirección a una página diferente. La página no encontrada tampoco debería redirigir, de esta manera el usuario aún puede ver la URL no válida en la barra de la URL del navegador si ingresa un nombre de usuario no válido.

Mi archivo router.js:

this.route(''profile'', { controller: ''ProfileController'', path: ''/:username'' });

Dentro de ProfileController , estoy tratando de reunir lo siguiente:

  • onBeforeAction - muestra la pantalla de carga; determinar si existe un nombre de usuario (también conocido como si la URL es válida)
    • Mostrar vista no encontrada, perfil privado o perfil público
  • waitOn - espera a que se recuperen los datos del username de username antes de quitar la pantalla de carga
  • onAfterAction - eliminar la pantalla de carga

¡Gracias!


Afortunadamente, todas las características que estás buscando están disponibles como complementos horneados, por lo que ni siquiera tendrás que sumergirte en la definición de tus propios ganchos.

Tenga en cuenta que estoy usando iron:[email protected] , esto es importante para mantenerse al día con las últimas novedades, solo hay dos caprichos menores en este momento que espero que se solucionen pronto.

Comencemos con la publicación del perfil de usuario, que toma el nombre de usuario como argumento.

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

Continuemos con la plantilla de perfil, aquí no hay nada demasiado sofisticado, mostraremos el nombre de usuario como datos públicos y, si estamos viendo el perfil privado, mostraremos el nombre real del usuario que suponemos que está almacenado en 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>

Entonces tenemos que definir una ruta para la vista de perfil en la configuración del enrutador global:

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

Tenga en cuenta que iron:router ahora requiere que defina sus rutas y controladores de ruta en el directorio compartido (generalmente este es el lib/ dir en la raíz de su proyecto) disponible tanto para el cliente como para el servidor.

Ahora, para la parte más difícil, la definición 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 }); } });

Cuando iron:router detecta que está usando waitOn en un RouteController , ahora agregará automáticamente el hook de loading predeterminado que es responsable de procesar el loadingTemplate mientras la suscripción aún no está lista.

Me referiré ahora a los dos errores menores de los que he hablado al principio de mi respuesta.

Primero, la guía oficial de iron:router (que definitivamente debería leer) http://eventedmind.github.io/iron-router/ menciona que el nombre de la opción que debe pasar al plugin dataNotFoundTemplate es dataNotFoundTemplate pero a partir de 28- 09-2014 esto no funcionará, necesita usar el nombre heredado notFoundTemplate , esto probablemente se solucione en cuestión de días.

Lo mismo aplica para el código de mi función de data en el controlador: he utilizado la sintaxis contra-intuitiva Router.current().params para acceder a los parámetros de ruta cuando normalmente this.params habría sido la sintaxis regular apropiada. Este es otro problema que aún no se ha abordado. https://github.com/EventedMind/iron-router/issues/857