Meteor: страница профиля пользователя с железным маршрутизатором

Я изо всех сил пытаюсь создать страницу профиля пользователя, используя Iron Router, который находится по адресу localhost:3000/:username. Страница профиля должна иметь следующие характеристики:

  • Общий вид — любой может увидеть основную информацию о пользователе
  • Частный просмотр — если клиент посещает страницу своего профиля во время входа в систему, отображаются его или ее конфиденциальные пользовательские данные, и у них есть возможность редактирования.
  • Представление загрузки — во время загрузки данных профиля пользователя показывать экран загрузки.
  • Представление «Не найдено» — если в URL введено неверное имя пользователя, вернуть ненайденную страницу.

Общедоступное и частное представления должны существовать по одному и тому же URL-адресу. В зависимости от учетных данных клиента они видят одно или другое без перенаправления на другую страницу. Ненайденная страница также не должна перенаправляться, таким образом, пользователь все еще может видеть недействительный URL-адрес в строке URL-адреса браузера, если вводит недопустимое имя пользователя.

Мой файл router.js:

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

В ProfileController я пытаюсь собрать воедино следующее:

  • onBeforeAction - show loading screen; determine if username exists (aka if URL is valid)
    • Either show not found view, private profile, or public profile
  • waitOn - дождаться получения данных username перед удалением загрузочного экрана
  • onAfterAction - убрать загрузочный экран

Спасибо!


person Jon Cursi    schedule 28.09.2014    source источник


Ответы (1)


К счастью, все характеристики, которые вы ищете, доступны в виде встроенных плагинов, так что вам даже не придется углубляться в определение собственных крючков.

Обратите внимание, что я использую iron:[email protected], это важно, чтобы быть в курсе последних новостей, на данный момент есть только две незначительные особенности, которые, я надеюсь, скоро исправят.

Начнем с публикации профиля пользователя, который принимает имя пользователя в качестве аргумента.

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.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>

Затем нам нужно определить маршрут для представления профиля в глобальной конфигурации маршрутизатора:

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/ в корне вашего проекта), доступном как для клиента, так и для сервера.

Теперь самое сложное — определение 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
        });
    }
});

Когда iron:router обнаружит, что вы используете waitOn в RouteController, теперь он автоматически добавит хук loading по умолчанию, который отвечает за рендеринг loadingTemplate, пока подписка еще не готова.

Теперь я рассмотрю две незначительные ошибки, о которых я говорил в начале своего ответа.

Во-первых, официальное iron:router руководство (которое вам обязательно нужно прочитать) http://eventedmind.github.io/iron-router/ упоминает, что имя параметра, которое вы должны передать плагину dataNotFound, — dataNotFoundTemplate, но с 28-09-2014 это не будет работать, вам нужно использовать устаревшее имя notFoundTemplate, это, вероятно, будет исправлено в вопросе дней.

То же самое касается кода моей функции data в контроллере: я использовал контринтуитивный синтаксис Router.current().params для доступа к параметрам маршрута, когда обычно this.params был бы подходящим обычным синтаксисом. Это еще одна проблема, которую еще предстоит решить. https://github.com/EventedMind/iron-router/issues/857

person saimeunt    schedule 28.09.2014
comment
Большое спасибо за Вашу помощь! Эта функция Meteor.publish() отлично работала только для публикации выбранных данных о рассматриваемом пользователе. - person Jon Cursi; 29.09.2014
comment
Это отличная запись спасибо. Стоит отметить для будущих читателей, что этот код не будет работать с audit-argument-checks. пакет установлен. - person AlecRust; 27.10.2015
comment
Если у вас есть шаблон страницы профиля, как вы получаете значения полей пользователя этой конкретной страницы профиля на стороне js? - person Barry Michael Doyle; 04.02.2016