Knockoutjs Multiselect在使用viewbag时显示索引而不是文本值

时间:2017-05-21 18:10:08

标签: asp.net-mvc knockout.js viewbag

我正在使用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加载它。

1 个答案:

答案 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>