使用knockout动态显示/隐藏元素

show/hide elements dynamically using knockout

本文关键字:隐藏 元素 动态显示 knockout 使用      更新时间:2023-09-26

我有一个表,它有四列,即代码,名称,数量和价格。其中,我想动态地更改Quantity列的内容/元素。通常情况下,它应该显示的数量显示在它的元素,当用户单击元素,我想显示元素,以便用户可以编辑数量。我正试图按照"示例2"在这个knockout文档链接上实现。

下面是我的代码:

页面Viewmodel

function OrderVM (vm) {
    var self = this;
    self.OrderNo= ko.observable(vm.OrderNo());   
    .....
    .....
    self.OrderedProducts = ko.observableArray([]);
    for (i = 0; i < vm.OrderedProducts().length; i++) {
        var p = new ProductVM(vm.OrderedProducts()[i]);
        self.OrderedProducts.push(p);
    }
    .....
}
function ProductVM(vm) {
    var self = this;
    self.Code = ko.observable(vm.Code());
    self.Name = ko.observable(vm.Name());
    self.Quantity = ko.observable(vm.Quantity());
    self.Price = ko.observable(vm.Price());
    self.IsEditing = ko.observable(false);
    this.edit = function () {
        self.IsEditing(true);
    }
}

在我的Razor视图我有以下代码:

<tbody data-bind="foreach:OrderedProducts">
<tr>
    <td class="lalign"><span data-bind="text:Code"/></td>
    <td class="lalign"><span data-bind="text:Name" /></td>
    <td class="ralign" style="padding:1px!important;">
        <span data-bind="visible: !IsEditing(), text: Quantity, click: edit"
            style="width:100%;float:left;text-align:right;padding-right:10px;" />
        <input data-bind="value: Quantity,visible:IsEditing,hasfocus:IsEditing"
               style="width:100%;text-align:right;padding-right:10px;" />
    </td>
    <td class="ralign rightbordernone" style="padding-right:20px!important;"><span data-bind="text:Price"/></td>
</tr>

使用上面的代码,当我单击表的Quantity列中的span元素时,调用"edit"函数并将"IsEditing"值设置为true,但我没有看到在单元格中可见的输入元素。在点击span元素后,如果我使用"Inspect element"查看html,我仍然只能看到元素,而不是在我的视图的屏幕上,我既看不到span元素也看不到input元素。

这是一个非常简单的逻辑,并且按照预期执行,但是视图的最终结果不像预期的那样。有人能帮我检测出上面的代码有什么问题吗?

这个问题很棘手。这是因为span而不是自闭元素。

<td>
    <span data-bind="visible: !IsEditing(), text: Quantity, click: edit"></span>
    <input data-bind="value: Quantity, visible: IsEditing, hasfocus: IsEditing" />
</td>

这里是一个完整的演示:

function ProductVM(vm) {
    var self = this;
    self.Code = ko.observable(vm.Code());
    self.Name = ko.observable(vm.Name());
    self.Quantity = ko.observable(vm.Quantity());
    self.Price = ko.observable(vm.Price());
    self.IsEditing = ko.observable(false);
    this.edit = function () {
        self.IsEditing(true);
    }
}
ko.applyBindings({ OrderedProducts: [new ProductVM({
    Code: function() { return 1; },
    Name: function() { return "Apples"; },
    Quantity: function() { return 10; },
    Price: function() { return 12.50; }
})]})
span { padding: 5px; background: pink; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
(Click "10" e.g. the Quantity for demo.)
<table>
  <tbody data-bind="foreach: OrderedProducts">
    <tr>
      <td><span data-bind="text:Code"></span></td>
      <td><span data-bind="text:Name"></span></td>
      <td>
        <span data-bind="visible: !IsEditing(), text: Quantity, click: edit"></span>
        <input data-bind="value: Quantity, visible: IsEditing, hasfocus: IsEditing" />
      </td>
      <td><span data-bind="text:Price"></span></td>
    </tr>
  </tbody>
</table>

记住,同样适用于div元素,不要以自关闭的方式使用它们,否则Knockout会在您最意想不到的时候欺骗您。