【问题标题】:Populate textbox using knockout "data-bind=click"使用敲除“data-bind=click”填充文本框
【发布时间】:2014-09-29 02:08:55
【问题描述】:

不知道你能不能帮忙。刚开始使用 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>

淘汰赛的定义

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}"

我知道如果我调用一个可观察对象,我需要将它作为一个函数调用,但是当我执行以下操作时,文本框包含空字符串。

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

非常感谢任何建议。 谢谢

【问题讨论】:

  • 当你点击一行时你想发生什么?是否应该使用单击行中的数据填充只读部分?
  • 是的,没错。

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


【解决方案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 绑定到该行的点击事件。当点击事件被触发时,它会使用两个参数调用GetSelectedRole,数据(您的视图模型)和eventArgs。你有一个名为rollData 的函数,它永远不会被调用,因为它被GetSelectedRole 中的同名参数隐藏。因此,您将视图模型的可观察值设置为可观察值本身。所以本质上你有一个嵌套的 observable,所以当你试图获取 observable 值时,它会返回另一个 observable,当转换为字符串时,它会显示你在文本框中看到的 observable 包装函数。

【讨论】:

  • 谢谢。我也是这么想的。这个问题可能被我将视图模型声明为对象横向而不是函数的事实所掩盖。我将其更改为函数声明。不过,我还是想知道原来问题的原因。
  • 在这种情况下,如何获取嵌套的 observable 的值?或者有没有更好的方法来实现而不使用嵌套的 observable?
  • 所以我会按照我在原始答案中编写的方式来实现它,因为没有办法知道你在哪一行。在你的代码中你可以将RoleVM.RoleID(roleData.RoleID); 更改为RoleVM.RoleID(roleData.RoleID()); 它不会嵌套您的可观察对象,但值也不会改变。如果您真的想获得那种原生敲除功能,您可能想要放弃 MVC 视图绑定以支持完全使用敲除。
  • 我正在根据您的建议进行更改,并且有效。我排除了function roleData() 方法。但是,然后我更改为data-bind=click: function (data) { GetSelectedRole(data) } 我得到function c()...
  • data-bind=click: function (data) { GetSelectedRole(data) }data-bind=click: GetSelectedRole 相同,您认为该数据参数是什么?它包含您的整个淘汰视图模型。
【解决方案2】:

试试这样改

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);
}

【讨论】:

  • 感谢这个(不是双关语)。没有不同。我仍然在文本框中填充了“函数 c()...”。
  • 尝试删除括号 text:RoleID 而不是 text:RoleID()
  • “文本:RoleID”还是“值:RoleID”?目前,我将其设置为“值:”。没有不同。当我更改为“text:”时,出现以下错误“Uncaught NoModificationAllowedError: Failed to set the 'innerText' property on 'HTMLElement': The 'input' element does not support text inserts.”
  • 当我更改为“text:”时,我收到以下错误“Uncaught NoModificationAllowedError: Failed to set the 'innerText' property on 'HTMLElement': The 'input' element does not support text inserts. "
  • 抱歉输入应该是value:RoleID
猜你喜欢
  • 2018-05-25
  • 2017-10-10
  • 2013-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-18
相关资源
最近更新 更多