使用collection2和autoform

时间:2015-10-05 16:23:41

标签: mongodb meteor meteor-accounts meteor-autoform meteor-collection2

我一直坚持这个问题一天半。我要做的是在我的Meteor.User集合中创建一个userProfile部分。因此,当用户登陆“设置”页面时,他们可以更新他们的信息。这就是我的目标。

顺便说一句,我使用User Accounts包进行登录/注册程序。

更新:3 表单提交但没有插入/更新数据。我已经注释掉'Schema.User',因为如果我将它放入并将其附加到Meteor.users.attachSchema(Schema.User)。自动窗体加载字段。这就是我把Schema.UserProfile改为的原因。我检查了控制台日志,它给了我错误“[拒绝访问] 403”它必须是允许/拒绝冲突?我在这里列出了所有代码。

设置HTML:

<template name="settings">
<div class="text-center light-container" id="settings-section">
    {{> quickForm collection="Meteor.users" doc=currentUser id="userProfile" type="update"}}
</div>

在两个目录中设置JS

    Schema = {};

Schema.UserProfile = new SimpleSchema({
    userProfile: {
        type: Object
    },
    'userProfile.firstName':{
        type: String,
        label: "First Name",
        max: 80
    },
    'userProfile.lastName':{
        type: String,
        label: "Last Name",
        max: 80
    },
    'userProfile.gender':{
        type: String,
        label: "Gender",
        allowedValues: ["Male", "Female"]
    },
    'userProfile.birthday':{
        type: Date,
        label: "Date Of Birth",
        autoform: {
            type: "bootstrap-datepicker"
        }
    },
    address:{
        type: Object
    },
    'address.city':{
        type: String,
        label: "City/Province",
        max: 80
    },
    'address.state':{
        type: String,
        label: "State",
        max: 80
    },
    'address.country':{
        type: String,
        label: "Country",
        max: 80
    },
    /*privacy:{
        type: String,
        label: "Privacy",
        allowedValues: ["On", "Off"]
    }, */
    aboutYou:{
        type: String,
        label: "About You",
        autoform: {
            afFieldInput: {
                type: "textarea"
            }
        },
        max: 400
    },
    socialNetworks:{
        type: Object,
        label: "Social Networks"
    },
    'socialNetworks.facebook':{
        type: String,
        label: "Facebook",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    },
    'socialNetworks.instagram':{
        type: String,
        label: "Instagram",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    },
    'socialNetworks.tumblr':{
        type: String,
        label: "Tumblr",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    },
    'socialNetworks.twitter':{
        type: String,
        label: "Twitter",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    }
});


/* 
    Schema.User = new SimpleSchema({
        username: {
            type: String,
            regEx: /^[a-z0-9A-Z_]{3,15}$/,
            optional: true
        },
        emails: {
            type: [Object],
            // this must be optional if you also use other login services like facebook,
            // but if you use only accounts-password, then it can be required
            optional: true
        },
        "emails.$.address": {
            type: String,
            regEx: SimpleSchema.RegEx.Email
        },
        "emails.$.verified": {
            type: Boolean
        },
        createdAt: {
            type: Date
        },
        profile: {
            type: Schema.UserProfile,
            optional: true
        },
        services: {
            type: Object,
            optional: true,
            blackbox: true
        }/*,

        // Add `roles` to your schema if you use the meteor-roles package.
        // Option 1: Object type
        // If you specify that type as Object, you must also specify the
        // `Roles.GLOBAL_GROUP` group whenever you add a user to a role.
        // Example:
        // Roles.addUsersToRoles(userId, ["admin"], Roles.GLOBAL_GROUP);
        // You can't mix and match adding with and without a group since
        // you will fail validation in some cases.
        roles: {
            type: Object,
            optional: true,
            blackbox: true
        }

        */
    }); 

*/

Meteor.users.attachSchema(Schema.UserProfile);

Meteor.users.allow({
    insert: function(userId, doc) {
        // only allow posting if you are logged in
        console.log("doc: " + doc + " userId: " + userId);
        return !! userId;
    },
    update: function(userId, doc) {
        // only allow updating if you are logged in
        console.log("doc: " + doc + " userId: " + userId);
        return !! userId;
    },
    remove: function(userID, doc) {
        //only allow deleting if you are owner
        return doc.submittedById === Meteor.userId();
    }
});

设置客户端目录中的JS

/*
    var postHooks = {
        before: {
            insert: function(doc) {
                if(Meteor.userId()){
                    doc.userId = Meteor.userId();
                }

                return doc;
            }
        },
        docToForm: function(doc) {
            if (_.isArray(doc.tags)) {
                doc.tags = doc.tags.join(", ");
            }
            return doc;
        },
        formToDoc: function(doc) {
            if (typeof doc.tags === "string") {
                doc.tags = doc.tags.split(",");
            }
            return doc;
        }
    };

    AutoForm.addHooks('UserProfile', postHooks);

*/

如果有人能指出我真正有用的正确方向!!

2 个答案:

答案 0 :(得分:0)

您需要为个人资料创建架构,然后将其分配到profile字段中的用户对象架构。我在下面为你完成了这件事。

var Schema = {};

Schema.UserProfile = new SimpleSchema({
   firstName:{
        type: String,
        label: "First Name",
        max: 80
    },
    lastName:{
        type: String,
        label: "Last Name",
        max: 80
    },
    gender:{
        type: String,
        label: "Gender",
        allowedValues: ["Male", "Female"]
    },
    birthday:{
        type: Date,
        label: "Date Of Birth",
        autoform: {
            type: "bootstrap-datepicker"
        }
    },
    address:{
        type: Object
    },
    'address.city':{
        type: String,
        label: "City/Province",
        max: 80
    },
    'address.state':{
        type: String,
        label: "State",
        max: 80
    },
    'address.country':{
        type: String,
        label: "Country",
        max: 80
    },
    /*privacy:{
        type: String,
        label: "Privacy",
        allowedValues: ["On", "Off"]
    }, */
    aboutYou:{
        type: String,
        label: "About You",
        autoform: {
            afFieldInput: {
                type: "textarea"
            }
        },
        max: 400
    },
    socialNetworks:{
        type: Object,
        label: "Social Networks"
    },
    'socialNetworks.facebook':{
        type: String,
        label: "Facebook",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    },
    'socialNetworks.instagram':{
        type: String,
        label: "Instagram",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    },
    'socialNetworks.tumblr':{
        type: String,
        label: "Tumblr",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    },
    'socialNetworks.twitter':{
        type: String,
        label: "Twitter",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
   }
});

Schema.User = new SimpleSchema({
    username: {
        type: String,
        regEx: /^[a-z0-9A-Z_]{3,15}$/,
        optional: true
    },
    emails: {
        type: [Object],
        // this must be optional if you also use other login services like facebook,
        // but if you use only accounts-password, then it can be required
        optional: true
    },
    "emails.$.address": {
        type: String,
        regEx: SimpleSchema.RegEx.Email
    },
    "emails.$.verified": {
        type: Boolean
    },
    createdAt: {
        type: Date
    },
    profile: {
        type: Schema.UserProfile,
        optional: true
    },
    services: {
        type: Object,
        optional: true,
        blackbox: true
    },
    // Add `roles` to your schema if you use the meteor-roles package.
    // Option 1: Object type
    // If you specify that type as Object, you must also specify the
    // `Roles.GLOBAL_GROUP` group whenever you add a user to a role.
    // Example:
    // Roles.addUsersToRoles(userId, ["admin"], Roles.GLOBAL_GROUP);
    // You can't mix and match adding with and without a group since
    // you will fail validation in some cases.
    roles: {
        type: Object,
        optional: true,
        blackbox: true
    }
});

Meteor.users.attachSchema(Schema.User);

对于允许和拒绝规则,您可能希望确保userId与文档的_id匹配,而不是仅仅查看它们是否已登录。

答案 1 :(得分:0)

尝试此操作(搜索描述相关更改的注释的“注意”):

设置HTML:

<template name="settings">
<div class="text-center light-container" id="settings-section">
    {{! NOTE: the fields attribute tells quickForm which fields to display }}
    {{> quickForm collection="Meteor.users" fields="userProfile" doc=currentUser id="userProfile" type="update"}}
</div>

在两个目录中设置JS

Schema = {};

Schema.UserProfile = new SimpleSchema({
    userProfile: {
        type: Object
    },
    'userProfile.firstName':{
        type: String,
        label: "First Name",
        max: 80
    },
    'userProfile.lastName':{
        type: String,
        label: "Last Name",
        max: 80
    },
    'userProfile.gender':{
        type: String,
        label: "Gender",
        allowedValues: ["Male", "Female"]
    },
    'userProfile.birthday':{
        type: Date,
        label: "Date Of Birth",
        autoform: {
            type: "bootstrap-datepicker"
        }
    },
    address:{
        type: Object
    },
    'address.city':{
        type: String,
        label: "City/Province",
        max: 80
    },
    'address.state':{
        type: String,
        label: "State",
        max: 80
    },
    'address.country':{
        type: String,
        label: "Country",
        max: 80
    },
    /*privacy:{
        type: String,
        label: "Privacy",
        allowedValues: ["On", "Off"]
    }, */
    aboutYou:{
        type: String,
        label: "About You",
        autoform: {
            afFieldInput: {
                type: "textarea"
            }
        },
        max: 400
    },
    socialNetworks:{
        type: Object,
        label: "Social Networks"
    },
    'socialNetworks.facebook':{
        type: String,
        label: "Facebook",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    },
    'socialNetworks.instagram':{
        type: String,
        label: "Instagram",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    },
    'socialNetworks.tumblr':{
        type: String,
        label: "Tumblr",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    },
    'socialNetworks.twitter':{
        type: String,
        label: "Twitter",
        autoform: {
            placeholder: 'Username'
        },
        max: 50
    }
});

// NOTE: You need to use this schema because it is the schema for the collection you are updating.
Schema.User = new SimpleSchema({
    username: {
        type: String,
        regEx: /^[a-z0-9A-Z_]{3,15}$/,
        optional: true
    },
    emails: {
        type: [Object],
        // this must be optional if you also use other login services like facebook,
        // but if you use only accounts-password, then it can be required
        optional: true
    },
    "emails.$.address": {
        type: String,
        regEx: SimpleSchema.RegEx.Email
    },
    "emails.$.verified": {
        type: Boolean
    },
    createdAt: {
        type: Date
    },
    profile: {
        type: Schema.UserProfile,
        optional: true
    },
    services: {
        type: Object,
        optional: true,
        blackbox: true
    }/*,

    // Add `roles` to your schema if you use the meteor-roles package.
    // Option 1: Object type
    // If you specify that type as Object, you must also specify the
    // `Roles.GLOBAL_GROUP` group whenever you add a user to a role.
    // Example:
    // Roles.addUsersToRoles(userId, ["admin"], Roles.GLOBAL_GROUP);
    // You can't mix and match adding with and without a group since
    // you will fail validation in some cases.
    roles: {
        type: Object,
        optional: true,
        blackbox: true
    }

    */
}); 

// NOTE: Meteor.users is a collection of objects matching the Schema.user schema, so you need to use this schema.
Meteor.users.attachSchema(Schema.User);

Meteor.users.allow({
    /* NOTE: The client should not be allowed to add users directly!
    insert: function(userId, doc) {
        // only allow posting if you are logged in
        console.log("doc: " + doc + " userId: " + userId);
        return !! userId;
    },
    */
    update: function(userId, doc, fieldNames) {
        // only allow updating if you are logged in
        console.log("doc: " + doc + " userId: " + userId);
        // NOTE: a user can only update his own user doc and only the 'userProfile' field
        return !! userId && userId === doc._id && _.isEmpty(_.difference(fieldNames, ['userProfile'])); 
    },
    /* NOTE: The client should not generally be able to remove users
    remove: function(userID, doc) {
        //only allow deleting if you are owner
        return doc.submittedById === Meteor.userId();
    }
    */
});

设置客户端目录中的JS

/* NOTE: I don't think you need any of these hooks.
    var postHooks = {
        before: {
            insert: function(doc) {
                if(Meteor.userId()){
                    doc.userId = Meteor.userId();
                }

                return doc;
            }
        },
        docToForm: function(doc) {
            if (_.isArray(doc.tags)) {
                doc.tags = doc.tags.join(", ");
            }
            return doc;
        },
        formToDoc: function(doc) {
            if (typeof doc.tags === "string") {
                doc.tags = doc.tags.split(",");
            }
            return doc;
        }
    };

    AutoForm.addHooks('UserProfile', postHooks);

*/