使用knockout“data-bind = click”填充文本框

时间:2014-08-06 08:12:17

标签: c# javascript asp.net-mvc-4 knockout.js

我想知道你是否可以提供帮助。刚开始使用KnockoutJS,我在填写基于所选文本框的文本框时遇到问题。我确信这对训练有素的眼睛来说非常明显,但我似乎无法找到问题的原因。以下是我的实施。

public class RoleViewModel
{
    public int RoleID { get; set; }
    public string RoleName { get; set; }
    public string Description { get; set; }
    public int ApplicationID { get; set; }
    public string ApplicationName { get; set; }

}

public class RoleIndexViewModel
{
    public List<RoleViewModel> RolesList { get; set; }
    public RoleViewModel Rvm { get; set; }
}

下面的Index.cshtml

@model ExpensesOrganiser4.ViewModels.RoleIndexViewModel

@section scripts{
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/jqueryui")
    <script src="~/Scripts/knockout-2.1.0.js" type="text/javascript"></script>
    <script src="~/Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
    <script src="~/Scripts/Application/role.js" type="text/javascript"></script>
    <script type="text/javascript">
        RoleVM.ViewModel = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model)));
    </script>
}

<table>
    <tr>
        <th>@Html.DisplayNameFor(model => model.Rvm.RoleName)</th>
        <th>@Html.DisplayNameFor(model => model.Rvm.Description)</th>
        <th>@Html.DisplayNameFor(model => model.Rvm.ApplicationName)</th>

   </tr>

@foreach (var item in Model.RolesList) {
    <tr data-bind="click: GetSelectedRole" id="updtr">
        <td>@Html.DisplayFor(modelItem => item.RoleName)</td>
        <td>@Html.DisplayFor(modelItem => item.Description)</td>
        <td>@Html.DisplayFor(modelItem => item.ApplicationName)</td>
    </tr>
}
</table>

<table data-bind="visible: ReadOnlyMode">
<tr>
    <td><label for="RoleID">Role ID:</label></td>
    <td><input data-bind="value: RoleID()" type="text" id="RoleID" /></td>
</tr>
<tr>
    <td><label for="RoleName">Role Name:</label></td>
    <td><input data-bind="value: RoleName()" type="text" id="RoleName" /></td>
</tr>
<tr>
    <td><label for="Description">Role Description:</label></td>
    <td><input data-bind="value: Description()" type="text" id="Description" /></td>
</tr>
<tr>
    <td><label for="ApplicationName">Application:</label></td>
    <td><input data-bind="value: ApplicationName()" type="text" id="ApplicationName" /></td>
</tr>
</table>

Knockout的定义

var RoleVM = {
EditFields: ko.observable(false),
ReadOnlyMode: ko.observable(true),
DisplayEditRoleButton: ko.observable(true),
DisplayUpdateRoleButton: ko.observable(false),
RoleID: ko.observable($("#RoleID").val()),
RoleName: ko.observable($("#RoleName").val()),
OriginalRoleName: ko.observable($("#RoleName").val()),
Description: ko.observable($("#Description").val()),
OriginalDescription: ko.observable($("#Description").val()),
ApplicationName: ko.observable($("#ApplicationName").val()),
OriginalApplicationName: ko.observable($("#ApplicationName").val()),
MessageBox: ko.observable(""),
SelectedRow: ko.observable(),
GetSelectedRole: function (roleData) {
    RoleVM.RoleID(roleData.RoleID);
    RoleVM.RoleName(roleData.RoleName);
    RoleVM.Description(roleData.Description);
    RoleVM.ApplicationName(roleData.ApplicationName);
}
};

function roleData(data) {
this.RoleID = ko.observable(data.RoleID);
this.RoleName = ko.observable(data.RoleName);
this.Description = ko.observable(data.Description);
this.ApplicationName = ko.observable(data.ApplicationName);
}


ko.applyBindings(RoleVM);

当我点击时,我在文本框中得到以下内容

function c(){if(0<arguments.length){if(!c.equalityComparer||!c.equalityComparer
(d,arguments[0]))c.I(),d=arguments[0],c.H();return this}a.U.La(c);return d}"

我知道如果我调用一个observable,我需要将其称为函数,但是当我执行以下操作时,文本框中包含空字符串。

GetSelectedRole: function (roleData) {
    RoleVM.RoleID(roleData.RoleID());
    RoleVM.RoleName(roleData.RoleName());
    RoleVM.Description(roleData.Description());
    RoleVM.ApplicationName(roleData.ApplicationName());
}

非常感谢任何建议。 感谢

2 个答案:

答案 0 :(得分:1)

我不确定您当前解决方案中的数据可能来自哪里,所以我做了一些调整。

首先,我建议遵循为任何复杂度的视图模型使用函数的模式,因为它往往会使事情变得更容易。

var RoleVM = function () {
    var self = this;
    self.EditFields = ko.observable(false);
    self.ReadOnlyMode = ko.observable(true),
    self.DisplayEditRoleButton = ko.observable(true),
    self.DisplayUpdateRoleButton = ko.observable(false),
    self.RoleID = ko.observable($("#RoleID").val()),
    self.RoleName = ko.observable($("#RoleName").val()),
    self.OriginalRoleName = ko.observable($("#RoleName").val()),
    self.Description = ko.observable($("#Description").val()),
    self.OriginalDescription = ko.observable($("#Description").val()),
    self.ApplicationName = ko.observable($("#ApplicationName").val()),
    self.OriginalApplicationName = ko.observable($("#ApplicationName").val()),
    self.MessageBox = ko.observable(""),
    self.SelectedRow = ko.observable(),
    self.GetSelectedRole = function (roleId, roleName, description, applicationName) {
        self.RoleID(roleData.RoleId);
        self.RoleName(roleData.RoleName);
        self.Description(roleData.Description);
        self.ApplicationName(roleData.ApplicationName);
    }
};

你可以按如下方式绑定它:

ko.applyBindings(new RoleVM());

然后你可以使用包装函数调用GetSelectedRole,这样你就可以使用一些Razor传递数据。

@foreach (var item in Model.RolesList) {
    <tr data-bind="click: function () { GetSelectedRole(@item.RoleID, @item.RoleName, @item.Description, @item.ApplicationName) }" id="updtr">
        <td class="role-name">@Html.DisplayFor(modelItem => item.RoleName)</td>
        <td class="description">@Html.DisplayFor(modelItem => item.Description)</td>
        <td class="application-name">@Html.DisplayFor(modelItem => item.ApplicationName)</td>
    </tr>
}

在您的解决方案中,您GetSelectedRole绑定了该行的click事件。当click事件被触发时,它会调用GetSelectedRole两个参数,data(你的viewmodel)和eventArgs。您有一个名为rollData的函数,它永远不会被调用,因为它被GetSelectedRole内的同名参数隐藏。因此,您将viewmodel的可观察值设置为observable本身。所以本质上你有一个嵌套的observable,所以当你试图获得observable值时,它会返回另一个observable,转换为string时会显示你在文本框中看到的可观察包装函数。

答案 1 :(得分:0)

尝试像这样更改

data-bind="click: GetSelectedRole.bind($data)"

还可以使用this

更改您的功能
GetSelectedRole: function (roleData) {
    this.RoleID(roleData.RoleID);
    this.RoleName(roleData.RoleName);
    this.Description(roleData.Description);
    this.ApplicationName(roleData.ApplicationName);
}