Meteor: Halaman Profil Pengguna dengan Iron Router

Saya kesulitan membuat halaman profil pengguna menggunakan Iron Router yang terletak di localhost:3000/:username. Halaman profil harus memiliki karakteristik berikut:

  • Tampilan publik - siapa pun dapat melihat informasi dasar tentang pengguna
  • Tampilan pribadi - jika klien mengunjungi halaman profilnya sendiri saat masuk, data pengguna sensitifnya akan ditampilkan dan mereka memiliki kemampuan mengedit
  • Tampilan pemuatan - saat data profil pengguna diambil, tampilkan layar pemuatan
  • Tampilan tidak ditemukan - jika nama pengguna yang dimasukkan ke dalam URL tidak valid, kembalikan halaman tidak ditemukan.

Tampilan publik dan tampilan pribadi harus ada di jalur URL yang sama. Bergantung pada kredensial klien, mereka melihat satu atau yang lain tanpa mengalihkan ke halaman lain. Halaman yang tidak ditemukan juga tidak boleh dialihkan, dengan cara ini pengguna masih dapat melihat URL yang tidak valid di bilah URL browser jika memasukkan nama pengguna yang tidak valid.

File router.js saya:

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

Dalam ProfileController, saya mencoba mengumpulkan yang berikut ini:

  • onBeforeAction - show loading screen; determine if username exists (aka if URL is valid)
    • Either show not found view, private profile, or public profile
  • waitOn - tunggu data username diambil sebelum menghapus layar pemuatan
  • onAfterAction - hapus layar pemuatan

Terima kasih!


person Jon Cursi    schedule 28.09.2014    source sumber


Jawaban (1)


Untungnya, setiap karakteristik yang Anda cari tersedia dalam bentuk plugin sehingga Anda bahkan tidak perlu mendalami definisi hook Anda sendiri.

Perhatikan bahwa saya menggunakan iron:[email protected], ini penting untuk mengikuti perkembangan terbaru, hanya ada dua keanehan kecil saat ini yang saya harap akan segera diperbaiki.

Mari kita mulai dengan publikasi profil pengguna, yang menggunakan nama pengguna sebagai argumen.

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

Mari kita lanjutkan dengan templat profil, tidak ada yang terlalu mewah di sini, kami akan menampilkan nama pengguna sebagai data publik, dan jika kami melihat profil pribadi, tampilkan nama asli pengguna yang kami asumsikan disimpan di 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>

Kemudian kita perlu menentukan rute untuk tampilan profil di konfigurasi router 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"
});

Perhatikan bahwa iron:router sekarang mengharuskan Anda menentukan rute dan pengontrol rute di direktori bersama (biasanya ini adalah direktori lib/ di root proyek Anda) yang tersedia untuk klien dan server.

Sekarang untuk bagian tersulit, definisi 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
        });
    }
});

Saat iron:router mendeteksi bahwa Anda menggunakan waitOn di RouteController, sekarang secara otomatis akan menambahkan kait loading default yang bertanggung jawab untuk merender loadingTemplate saat langganan belum siap.

Sekarang saya akan mengatasi dua bug kecil yang telah saya bicarakan di awal jawaban saya.

Pertama, panduan resmi iron:router (yang pastinya harus Anda baca) http://eventedmind.github.io/iron-router/ menyebutkan bahwa nama opsi yang harus Anda berikan ke plugin dataNotFound adalah dataNotFoundTemplate tetapi pada 28-09-2014 ini tidak akan berfungsi, Anda perlu menggunakan nama lama notFoundTemplate, ini mungkin akan diperbaiki dalam suatu masalah hari.

Hal yang sama berlaku untuk kode fungsi data saya di pengontrol: Saya telah menggunakan sintaks kontra-intuitif Router.current().params untuk mengakses parameter rute padahal biasanya this.params adalah sintaks reguler yang sesuai. Ini adalah masalah lain yang belum diatasi. https://github.com/EventedMind/iron-router/issues/857

person saimeunt    schedule 28.09.2014
comment
Terima kasih banyak atas bantuan Anda! Fungsi Meteor.publish() berfungsi dengan baik hanya untuk menerbitkan data pilihan tentang pengguna yang dimaksud. - person Jon Cursi; 29.09.2014
comment
Ini adalah tulisan yang bagus, terima kasih. Perlu diperhatikan bagi pembaca selanjutnya, kode ini tidak akan berfungsi dengan audit-argument-checks paket diinstal. - person AlecRust; 27.10.2015
comment
Jika Anda memiliki templat halaman profil, bagaimana Anda mendapatkan nilai bidang pengguna halaman profil tertentu di sisi js? - person Barry Michael Doyle; 04.02.2016