带有对象集合的Json数据被映射为可观察的,而不是可观察的数组
Json data with collection of objects gets mapped as observable instead of observable array
在我的页面上,我想通过Json接收用户帐户的视图模型。数据包括一些用户详细信息,如真实姓名和电子邮件地址等。除此之外,我还需要显示(并更改)特定用户所属的组,以及所有可用用户组的列表,以便为用户选择其他用户组。
数据会被正确加载,用户详细信息也会按预期显示。对于小组分配,我创建了两个列表框。第一个显示当前分配的组,另一个显示所有现有组。我想使用两个按钮将所选项目从"所有组"列表移动到"所选组"列表("添加到选择"),另一个按钮将项目从"选定组"列表中删除,并将其放回"全部组"列表。
两个列表都会正确填充。当我在运行时查看我的viewModel时,我可以看到viewModel.AllGroups()
是一个可观察的对象,其_latestValues
中有许多组对象(组对象由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,这样映射插件才能正确识别数据的结构。
问题出在来自服务器的JSON中:
"SelectedGroups":null,
因为你的属性是null
,所以映射插件不知道你想要一个数组,它只是为你创建了一个ko.observable
。
要修复它,您需要更改服务器端以发送一个空数组,而不是null
:
"SelectedGroups": [],
在这种情况下,映射插件将创建一个空的CCD_。
但是,如果您不能更改服务器端,您也可以告诉映射插件如何使用create
映射选项来映射"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。
- knockoutjs可观察数组
- 将js对象更改为使用嵌套的可观察数组敲除js视图模型
- 敲除:可观察数组没有被正确绑定——只有1个结果显示,而api返回6
- $scope$观察数组中的一个特定对象——Angular JS控制器
- 如何使用敲除映射将空值映射到空的可观察数组
- 以不同的方式对相同的可观察数组进行排序
- 如何在 Knockout.js 中更新可观察数组后立即使用 DOM 容器
- Knockout.js:如何根据可观察数组中的更改更改值
- 使用挖空.js如何刷新 Select 元素中的可观察数组
- 更新挖空中可观察数组中项目的属性
- 动态地向可观察数组中的特定项添加绑定(例如hasfocus)
- AngularJS:观察数组属性
- 对可观察数组foreach的更新删除了格式化knockoutjs
- 当通过Ajax成功回调更新可观察数组时,启用绑定中断
- 如何获取复选框值并将其插入到挖空中的可观察数组中
- 剔除不更新辅助表的可观察数组
- 如何让Knockout可观察数组与jQuery对话框一起工作
- 更改可观察数组会更改自定义绑定处理程序knockoutjs的可见性
- 正在更新Knockoutjs可观察数组项
- Knockout,无法解析空可观察数组中的绑定错误