我正在使用viewbag来加载多选列表的选项。但是,当我这样做时,我得到一个基于1的索引而不是实际的文本值。
<td> @Html.DropDownList("MAMUserGroupName", (MultiSelectList)ViewBag.MAMUserGroupsList, new { multiple = "multiple", data_bind = "selectedOptions:MAMUserGroups" })</td>
这是viewModel:
var viewModel = new UserModel([
{
id: ko.observable(""), firstName: ko.observable(""), lastName: ko.observable(""),MAMUserGroups: ko.observable()
}
]);
当选择值并且我调用了淘汰保存功能时,值为1,2和/或3,而不是实际的文本值;在这种情况下,“Group1”,“Group2”,“Group3”
当我这样做时,标准的硬编码选项方式就像这里一样工作:Knockout selectedOptions example。但在我的情况下,我需要从viewbag加载它。
答案 0 :(得分:0)
@ Html.DropdownList是列表的服务器端呈现,knockoutjs是列表的客户端呈现,两者不知道彼此。您需要做的是将列表呈现到页面上的javascript数组,或者通过Ajax / fetch从服务器检索它然后呈现给客户端。因此,使用您的代码示例,我将使用您需要的数据填充knockoutjs视图模型。如下所示。
var PageModel = function(data) {
var users = ko.observableArray();
var userGroups = ko.observableArray();
var mappedUsers = data.Users.map(function(user) {
return {
id: ko.observable(user.id),
firstName: ko.observable(user.firstName),
lastName: ko.observable(user.lastName),
mameUserGroups: ko.observableArray()
};
});
users(mappedUsers);
var mappedGroups = data.MAMUserGroups.map(function(item) {
return {
id: item.id,
name: item.name
};
});
userGroups(mappedGroups);
return {
users: users,
userGroups: userGroups
};
};
ko.applyBindings(new PageModel({
//****** Data loaded here ******
Users: [{
id: 1,
firstName: "test",
lastName: "user 1"
}, {
id: 2,
firstName: "test",
lastName: "user 2"
}, {
id: 3,
firstName: "test",
lastName: "user 3"
}, {
id: 4,
firstName: "test",
lastName: "user 4"
}],
MAMUserGroups: [{
id: 1,
name: "User Group 1"
}, {
id: 2,
name: "User Group 2"
}, {
id: 3,
name: "User Group 3"
}, {
id: 4,
name: "User Group 4"
}]
}));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table>
<tbody data-bind="foreach: users">
<tr>
<td data-bind="text: firstName"></td>
<td data-bind="text: lastName"></td>
<td>
<select data-bind="options: $parent.userGroups, selectedOptions: mameUserGroups, optionsText: 'name' " size='5' multiple='true'> </select>
</td>
</tr>
</tbody>
</table>
<ul data-bind="foreach: users">
<li>
<span data-bind="text: firstName"></span><span data-bind="text: lastName"></span>
<ul data-bind="foreach: mameUserGroups">
<li data-bind="text: name"></li>
</ul>
</li>
</ul>
<!--
<script type="text/javascript">
// Render the data on the page server side to then be used client side
$().ready(function(){
var users = @(Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.Users)));
var mamUserGroups = @(Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.mamUserGroups)));
});
</script>
-->
编辑Ajax实施
这是一种方法。可能更多的代码而不是需要但我喜欢将事情分解为单独的责任区域。如果您尝试从此处运行此代码段,您将获得的是用户和用户组的错误警报和已完成的警报。
var app = window.app || {};
app.modelMap = (function() {
function userMap(user) {
return {
id: ko.observable(user.id),
firstName: ko.observable(user.firstName),
lastName: ko.observable(user.lastName),
mameUserGroups: ko.observableArray()
};
}
function userGroupMap(userGroup) {
return {
id: userGroup.id,
name: userGroup.name
};
}
return {
userMap: userMap,
userGroupMap: userGroupMap
}
})();
app.data = (function() {
function getUserGroups() {
return $.get("<MAMUSerGroup_URL_HERE>").then(function(data) {
alert("successfully retrieved user group data");
return data.map(app.modelMap.userGroupMap);
})
.fail(function() {
alert("error");
})
.always(function() {
alert("finished");
});
};
function getUsers() {
return $.get("<Users_URL_HERE>").then(function(data) {
alert("successfully retrieved user data");
return data.map(app.modelMap.userMap);
})
.fail(function() {
alert("error");
})
.always(function() {
alert("finished");
});
}
return {
getUserGroups: getUserGroups,
getUsers: getUsers
}
})();
app.pageModel = (function() {
var users = ko.observableArray();
var userGroups = ko.observableArray();
function getUsers() {
return app.data.getUsers().done(users);
}
function getUserGroups() {
return app.data.getUserGroups().done(userGroups);
}
function activate() {
getUsers();
getUserGroups();
}
var vm = {
users: users,
userGroups: userGroups,
activate: activate
};
return vm;
})();
var vm = app.pageModel;
vm.activate();
ko.applyBindings(vm);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>