在我的页面上,我想通过Json接收用户帐户的viewmodel。数据包括一些用户详细信息,如真实姓名和电子邮件地址等。除此之外,我还需要显示(和更改)特定用户所属的组,以及所有可用用户组的列表以选择其他为用户提供的。
正确加载数据并按预期显示用户详细信息。对于组分配,我创建了两个列表框。第一个显示当前分配的组,另一个显示所有现有组。我想使用两个按钮将所选项目从“所有组”列表移动到“选定组”列表(“添加到选择”),另一个按钮从“选定组”列表中删除项目并将其放回进入“所有群组”列表。
两个列表都已正确填充。当我在运行时查看我的viewModel时,我可以看到viewModel.AllGroups()
是一个可观察的,在_latestValues
中有一些 group 对象(一个组对象由一个 Id 和 GroupName )。我也可以直接正确访问它们,例如点击按钮进行测试触发
alert(viewModel.AllGroups()[0].GroupName());
这给出了正确的文字,所以基本上一切都已到位。但是当我尝试手动将组对象添加到SelectedGroups
集合时,似乎viewModel.SelectedGroups
和viewModel.AllGroups
没有.push
或.remove
,因为它们不是一个可观察的数组,但只是一个可观察的数据!?
这是我的JS代码:
<script type="text/javascript">
var viewModel;
$(function () {
$.ajaxSetup({ cache: false });
$.getJSON('/Admin/GetEditWebUserData?Id=@WebUserId', function (data) {
viewModel = ko.mapping.fromJS(data);
Selected = viewModel.SelectedGroups();
viewModel.addToSelection = function () {
viewModel.SelectedGroups().push({ GroupName: 'Test Group', Id: '123' });
}
ko.applyBindings(viewModel, document.getElementById('data'));
});
});
</ script>
...这里是带有绑定的HTML部分:
<div id="data">
<div class="WebUserGroupEditBox">
Member of:
<select size="5" data-bind="options: SelectedGroups(), optionsText: 'GroupName', optionsValue: 'Id'"></select>
<button data-bind="click: removeFromSelection">remove from selection</button>
</div>
<div class="WebUserGroupEditBox">
Available groups:
<select multiple="multiple" size="5" data-bind="options: AllGroups(), optionsText: 'GroupName', optionsValue: 'Id'"></select>
<button data-bind="click: addToSelection">add to selection</button>
</div>
</div>
当我点击添加到选择按钮时,出现错误,告诉我.push
不存在。我认为这可能是映射问题。除了自己实现映射外,还有什么我可以做的吗?
更新:这是一些Json数据(直接从服务器响应中嗅探):
{
"FirstName":"Rob",
"LastName":"Smith",
"UserName":"rsmith",
"Email":"rsmith@test.com",
"SelectedGroups":null,
"AllGroups":[
{
"Id":0,
"GroupName":"Managers",
"AllowCommands":true,
"AllowParameters":true
},
{
"Id":1,
"GroupName":"Guests",
"AllowCommands":false,
"AllowParameters":false
}
]
}
解决方案:
问题不在于映射本身,而在于构造Json数据的服务器端代码。正如nemesv在他的评论中指出的那样,当没有项目时,需要有一个空数组而不是null,以便映射插件正确识别数据的结构。
答案 0 :(得分:0)
问题在于你的JSON来自服务器:
"SelectedGroups":null,
由于您的属性为null
,因此映射插件无法在此处创建数组,因此只需为您创建ko.observable
。
要解决此问题,您需要更改服务器端以发送空数组而不是null
:
"SelectedGroups": [],
在这种情况下,映射插件将创建一个空的ko.observableArray
。
但是,如果您无法更改服务器端,您还可以告诉映射插件如何使用create
mapping option映射"SelectedGroups"
属性:
var mapping = {
"SelectedGroups": {
create: function(options){
if (!options.data) // no data from the server return an empty array
return ko.observableArray();
// SelectedGroups is not empty continue the mapping
return ko.mapping.fromJS(options.data);
}
}
};
var vm = ko.mapping.fromJS(data, mapping);
演示JSFiddle。