這是我的視圖模型。如何將數據綁定到敲除對象的列表?
服務器端:
public class ShoppingListModel
{
public string Name { get; set; }
public List<ItemModel> Items{ get; set; }
public ShoppingListModel()
{
Items=new List<ItemModel>();
}
}
在客戶端,我用knockout.mapping
。
ShoppingListModel = function(data) {
var vm = ko.mapping.fromJSON(data);
return vm;
};
要綁定服務器端模式向客戶端模型:
@{
var jsonSerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
var data = new JavaScriptSerializer().Serialize(JsonConvert.SerializeObject(Model, jsonSerializerSettings));
}
@section scripts {
<script src="~/App/ShoppingListModel.js"></script>
<script>
var vm = ShoppingListModel(@Html.Raw(data));
ko.applyBindings(vm);
</script>
}
上面的代碼:
- 使用
JSON.NET
到服務器側Model
序列化爲般地裝載JSON。 - 構建客戶端視圖模型。
- ko.applyBinding()
現在我要帶的雙向綁定的優勢。
首先,我對Name
測試:
@Html.HiddenFor(model => model.Name, new { @data_bind="value:name"})
<input type="text" data-bind="value:name"/>
很順利,我可以在一個文本編輯input
的Name
價值,堅持價值爲隱藏input
。提交表單時,更新的值可能會達到POST操作。
現在的問題:如何在列表上實現綁定?
我的測試是從「項目」列表中刪除一個項目:
@Html.HiddenFor(model => model.Items, new { data_bind = "value: items" })
<tbody data-bind="foreach:items">
<tr>
<td>
<span data-bind="text:name"></span>
</td>
<td><span data-bind="text:count"></span></td>
<td>
<button class="btn btn-xs" data-bind="click:$parent.remove">
<i class="fa fa-trash"></i>
</button>
</td>
</tr>
</tbody>
一個console.log()
告訴我,客戶端模型已經更新,但是這一次,在結合上HiddenFor
從來沒有成功了!提交表格時,Items
始終爲空。
我想這是合理的,因爲在HTML:
<input type="hidden" value="xxx" />
,我們期待一個輸入的值是一個簡單的值。
我在想從那裏通過列表和數據綁定循環。但這也很困難。淘汰賽foreach
在tbody
標記,而C#foreach
被放置在tr
(在tbody
內)。
那麼綁定列表的正確方法是什麼?
這是基於法比奧的建議我的解決方案:
- 在客戶端KO模型,
添加一個計算值的列表裝訂成JSON字符串。
vm.itemsJson = ko.computed(function() {
return ko.toJSON(vm.items);
},this);
- 在HTML視圖,
- 在服務器側視圖模型,
- 將json字符串解析到服務器端的List中。
添加一個隱藏的輸入以保持JSON字符串和後與我們的形式。
<input name="itemsjson" type="hidden" data-bind="value:itemsJson"/>
除了
public List<ItemModel> Items{ get; set; }
添加另一個字符串屬性保持張貼JSON。
public string ItemsJson { get; set; }
在這一點上,我們都能夠看到成功發送到控制器動作ItemsJson
值。
既然是打字模型,我們要用JSON.Net
進行反序列化。
var items=JArray.Parse(model.ItemsJson);
model.Items = items.
Select(i => new ItemModel {Name = (string) i["name"], Count = (int) i["count"]})
.ToList();
return View(model);
請務必使用JArray.Parse()
的List
而不是JObject.Parse()
。
它的工作原理。
我們來看看是否有比手動解析json字符串更好的方法。否則,我會在本週末之後將法比奧的答案標記爲我們的解決方案。
不錯的建議。所以當隱藏輸入中的json值被POST到服務器時,那個Json值會自動被解析成一個List,我猜?讓我嘗試並確認它。 – Blaise
不幸的是沒有。隱藏輸入中的json是一個字符串,不會自動解析到服務器端模型中。需要某種方式在服務器端進行模型綁定。 – Blaise
我已經使它與手動json解析一起工作。在問題的底部發布整個事情。想知道是否有更優雅的方式。十分感謝你」。 – Blaise