如何将 post 多对多关系数据从 AngularJS 转换为 restful api?

How to post many-to-many relational data to a restful api from AngularJS?

我的网络应用程序中有一个主题管理模块。我在服务器端使用 SequelizeJS。

型号是:

module.exports = function(sequelize, DataTypes) {

var Theme = sequelize.define('Theme', {
    name: DataTypes.STRING,
    description: DataTypes.STRING

}, {
    associate: function(models) {
        Theme.belongsToMany(models.Option, { through: models.ThemeOptions })
    },
    tableName: 'themes'
});

return Theme;
};


module.exports = function(sequelize, DataTypes) {

var ThemeOptions = sequelize.define('ThemeOptions', {
}, {
    tableName: 'theme_options'
});

return ThemeOptions;
};


module.exports = function(sequelize, DataTypes) {

var Option = sequelize.define('Option', {
    key: DataTypes.STRING,
    value: DataTypes.STRING

}, {
    associate: function(models) {
        Option.belongsToMany(models.Theme, { through: models.ThemeOptions })
    },
    tableName: 'options',
    timestamps: false
});

return Option;
};

在 /#/themes/create 状态下,我想创建一个带有一些选项的主题,例如颜色代码。

我正在用

创建主题
 $http.post('/themes', themeData)

然后就是这样,我正在创建选项。最后我应该 post 多对多数据到主题选项。所以对于一个有 10 个选项的主题,我 posting 了 21 次。

将多对多数据post发送到 REST 服务器的最佳方法是什么?

在 Symfony2 世界中,有一个 bundle,SonataAdminBundle,可以生成管理界面。使用实体 类(此处为 OptionTheme),它会生成所有页面,列出、创建和编辑这些实体。它生成处理多对多关系的表单。它是如何管理的:

用户查询ManyToMany关系任一侧实体的creation/edition形式。在必须显示多对多关联的表单中,它显示一个 <select>,例如 Select2,这是一个 <select> 和一些 jQuery。列表的每个元素 与数据库中的相应 ID 链接,类似于 <option value="13456">Option #3</select>。对于多对多关系,我们可以同时 select 多个字段。在内部,它使用 <select>.

构建一个 选项 ID 数组

如果我们想动态添加一个反向实体(这里,反向实体是选项,我认为......),有一个按钮可以打开一个选项创建表单,一旦新选项是添加后,它将新创建的选项添加到<select>中,因此用户可以立即在表单中添加它。 然后,它发送使用表单构建的选项 ID 数组。

我认为这个策略可以满足您的需求。

真的不知道您是如何处理路由或后端的。假设您使用的是 express 并且您的选项是以前创建的,我建议创建一个新的 post 路由来处理每个 ThemeOptions

app.post('/themeOptions', { ThemeId: 1, OptionId:2 });

并使用该信息创建一个 ThemeOptions 实例以将 Theme 与某些 Option 连接起来。

这可以将您的 post 数量减少一半 + 1(Theme 一个,每个 ThemeOption 一个)。

另一种解决方案可能是管理一个 ThemeOptions 数组并使用 ThemeOptions#bulkCreate 一次创建它们,仅使用 2 posts(一个用于 Theme一个代表所有 ThemeOptions.

会是这样的:

app.post('/themeOptions', { 
  options: [{
    ThemeId: 1, 
    OptionId:2
  }, {
    ThemeId: 1, 
    OptionId:3
  } 
  // and so on...
}); 

这些解决方案中的每一个都可能涉及更多逻辑来管理每个前端请求,但也可能增加前端行为。

最终(在后端更复杂)的解决方案是发送一个唯一的 post 发送 ThemeOptions 数组,并创建所有ThemeOptions 创建 Theme

之后
// frontend
app.post('/theme', { 
  theme: {
    name: 'John',
    description: 'Doe'
  },
  options: [2, 3 /* and so on ... */]
}); 

// backend
Theme.create(req.body.theme).on('success', function (theme) {
   var options = req.body.options.map(function (option) {
     return {
       ThemeId: theme.id, 
       OptionId: option
     };
   });

   ThemeOptions.bulkCreate(options);
})