1

几天来,我一直在为这个问题绞尽脑汁,无法想出一个像样的解决方案。

我有以下型号

{
  "id": "123",
  "key1": "foo",
  "key2": "bar",
  "metadata": {
    "height": 1,
    "width": 1  
  },
  "userPrefs": [
     {
       "name":"firstName",
       "displayName":"First name",
       "required":true,
       "dataType":"text",
       "defaultValue":"enter first name",
       "value": ""
     },
     ......
  ]
}

我的视图使用这个模型,特别是 userPrefs,来创建一个编辑表单。因此,例如 userPrefs 会生成这样的输入

<input type="text" id="firstName" name="firstName" value="" placeholder="enter first name" required />

然后用户可以输入名字的值——例如“John”并点击保存。在发出 PUT 请求之前,我需要将此表单数据映射回模型。

所以我劫持了提交事件并做

this.$('form').serializeArray()

这将返回一个键/值对数组,例如

[{"firstName": "John"}]

现在我遇到的问题是如何最好地将这些值映射回模型中正确的 userPref。

我玩弄了“假设” 5 个 userPrefs 会导致 5 个输入的想法。然后我可以使用带有索引的迭代器来更新正确的 userPref。但是我们知道,一个未选中的复选框不会被提交,所以一个简单的迭代器不会工作。

然后我尝试获取每个序列化值并循环通过 userPrefs 进行匹配。但这仍然会因上面提到的复选框问题而失败。

谁能看到一个优雅的解决方案?

  • 我应该使用更好的 json 结构来解决这个问题吗?可能是一个仅包含 userPrefs 的单独模型
  • 我如何知道用户是否取消选中复选框并能够更新我的模型
4

2 回答 2

1

最后我想出了一个相当简单的解决方案。

var self = this;
var userPrefs = this.model.get('userPrefs');

// loop through the prefs and update one at a time....
_.each(userPrefs, function(pref, index) {       
   var item = self.$('#' + userPrefs[index].name); // userPref DOM item
   if (item[0].type === 'checkbox') {
      userPrefs[index].value = item[0].checked;
   } else {
      userPrefs[index].value = item[0].value;
   }
});

// update the model 
this.model.set('userPrefs', userPrefs);

因为我首先使用了每个 userPref 来构建表单,所以我可以遍历它们并查询 dom。

然后我可以将值插入回模型中。

我可以看到它有两个缺点

  • 我正在更新模型中的值,无论它是否实际发生了变化
  • 它有一个硬编码的复选框检查

但对于我的用例,这是可以接受的。

于 2013-09-19T08:51:34.130 回答
0

这是我能想到的解决方案。首先,您不应该将简单的 JSON 作为您的模型,而应该有一个关联(一对多,model to userPrefs)。查看Backbone Associations以建立关系。在Backbone Associations上下文中,您需要AssociatedModel为您的外部创建一个modeluserPref然后将userPrefs集合添加到您的外部模型中。(这在 Backbone Associations 教程中进行了解释。)

当您edit form从特定userPref模型创建时,将此模型的存储id在表单中的某处(隐藏字段或数据属性),以便您以后可以使用它从集合中找到相应的userPref模型并相应地更新。userPrefs

希望这可以帮助。

于 2013-09-18T14:05:23.790 回答