“路径上的值1,1的“转换为数字失败”

时间:2018-12-03 19:55:28

标签: javascript node.js mongodb mongoose

我正在尝试建立具有某些特权的用户模型。

模式如下:

var mongoose = require("mongoose"), 
    passportLocalMongoose = require("passport-local-mongoose");

let userSchema = new mongoose.Schema({
    username:
    {type: String,
    unique: true
    },
    password: String,
    privileges:
    [{
            region: { type: Number, unique: true },
            read: Number,
            write: Number,
            edit: Number
    }]
});

userSchema.plugin(passportLocalMongoose);

module.exports = mongoose.model("User", userSchema);

POST路由如下所示。

router.post('/register', function(req, res)
{
    console.log(req.body);
    User.register(new User({
        username: req.body.username,
        privileges:{
            region: req.body.privileges['region'],
            read: req.body.privileges['read'],
            write: req.body.privileges['write'],
            edit: req.body.privileges['edit']
        }
    }), req.body.password, function(err)
    {
        if(err)
        {
            console.log(err);
            res.redirect("/register");
        }
        else
        {
            console.log("fine");
            passport.authenticate('local', {
                successRedirect: '/',
                failureRedirect: '/login'
            })
        }
    })
});

<form action="/register" method="POST">
    <input type="text" name="username"><br/>
    <input type="password" name="password"><br/>
    <input type="text" name="privileges[region]"><br/>
    <input type="text" name="privileges[read]"><br/>
    <input type="text" name="privileges[write]"><br/>
    <input type="text" name="privileges[edit]"><br/>
    <input type="text" name="privileges[delete]"><br/>
    <button>Submit</button>
</form>

基本上,它应该像这样工作: 从表单中,我应该获得一系列特权。 现在,当我在像这样的字段中输入数据时: 测试 1234 1 2 1 1 1 1 1 1 (测试-用户名,1234-密码,1 2区域数组,1 1-读取数组,1 1写数组,1 1编辑数组)我收到此错误: click

现在我知道了原因-privileges [edit]是type =“ text”,它不能作为数字解析到DB中。但是为什么只进行编辑呢?我觉得很奇怪。

我尝试将输入类型更改为数字,但是之后我无法再输入数组。

我想我可能需要一个将文本转换成数字的中间件。我对吗?如果是这样,应该怎么做?它应该分别转换数组的每个元素还是整个数组?

谢谢。

1 个答案:

答案 0 :(得分:1)

在为User定义的架构中,privileges是具有该架构的子文档的数组。

{
    region: { type: Number, unique: true },
    read: Number,
    write: Number,
    edit: Number
}

设置此字段时,提供的数据需要匹配该架构。 例如

new User({
  username: req.body.username,
  privileges: [
    {
      region: ":region_value",
      read: ":read_value",
      write: ":write_value",
      edit: ":edit_value"
    },
    {
      region: ":region_value",
      read: ":read_value",
      write: ":write_value",
      edit: ":edit_value"
    },
    //....
  ],
})

我认为特权的设计是通过这种方式故意进行的,以允许用户拥有许多特权。

设置特权的一种直接方法是适当设计表单。表单字段可以允许设置多个特权。例如,要设置两个特权,可以通过以下方式编写标记来实现:

<input type="text" name="privileges[0][region]"><br/>
<input type="text" name="privileges[0][read]"><br/>
<input type="text" name="privileges[0][write]"><br/>
<input type="text" name="privileges[0][edit]"><br/>
<input type="text" name="privileges[0][delete]"><br/>

<input type="text" name="privileges[1][region]"><br/>
<input type="text" name="privileges[1][read]"><br/>
<input type="text" name="privileges[1][write]"><br/>
<input type="text" name="privileges[1][edit]"><br/>
<input type="text" name="privileges[1][delete]"><br/>

通过这种方式,req.body中的特权将具有正确的格式,例如

{ privileges:
  [ { region: '1', read: '2', write: '2', edit: '2', delete: '4' },
    { region: '2', read: '4', write: '4', edit: '4', delete: '4' } ] }

这样您就可以简单地编写

new User({
  username: req.body.username, 
  privileges: req.body.privileges
})

确保客户端传递正确的数据比事实之后尝试处理数据更直接。

这种形式的设计限制意味着必须提前确定用户可能具有的特权数量。解决此问题的方法是动态构建表单,并根据情况将控制权授予用户以添加更多特权。请参见以下示例,以了解有关操作方法的信息:

function addPrivilege(e) {
  e.preventDefault();
  const privileges =  $('.privileges');
  const lastCount = privileges.length;
  console.log($(this).data('template').replace(/:x:/g, lastCount))
  const template = $(this).data('template').replace(':x:', lastCount);
  
  privileges.after($('<div class="privileges"></div>').append(template))
}


$(document).ready(function () {

  $("#addPrivilegeBtn").on('click', addPrivilege);
});
.privileges {
  background: #ccc;
  padding: 8px 16px;
  margin: 4px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
  <div class="privileges">
    <input type="text" name="privileges[0][region]"><br/>
    <input type="text" name="privileges[0][read]"><br/>
    <input type="text" name="privileges[0][write]"><br/>
    <input type="text" name="privileges[0][edit]"><br/>
    <input type="text" name="privileges[0][delete]"><br/>
  </div>

  <button 
    id="addPrivilegeBtn"
    data-template='<input type="text"name="privileges[:x:][region]"><br/>
    <input type="text" name="privileges[:x:][read]"><br/>
    <input type="text" name="privileges[:x:][write]"><br/>
    <input type="text" name="privileges[:x:][edit]"><br/>
    <input type="text" name="privileges[:x:][delete]"><br/>'
  >Add privilege</button>
</form>