通过淘汰赛更新剃刀收集

时间:2018-04-29 09:20:04

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

我有这个UI

enter image description here

我的目标是在根据 ID 说明参数点击更新按钮后更新表格

我有以下代码

HTML

<table class="table table-bordered table-striped table-hover">
    <thead>
        <tr>
            <th>Id</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Products)
        {
            <tr>
                <td>@item.Id</td>
                <td>@item.Description</td>
            </tr>
        }
    </tbody>
</table>

<label>Id</label>
<input data-bind="value: productId" type="text" class="form-control" />

<br />

<label>Description</label>
<input data-bind="value: productDescription" type="text" class="form-control" />

<br />

<button class="btn btn-primary" data-bind="click: update">Update</button>

的JavaScript

<script type='text/javascript'>

            // Plain javascript alternative to jQuery.ready.
            (function () {

                // Convert server model to json object.
                var json = {"products":[{"id":1,"description":"Product A"},{"id":2,"description":"Product B"},{"id":3,"description":"Product C"}],"categoryName":"chocolates"};

                function viewModel()
                {
                    var index;

                    // Store default this to self, to be able use self in subfunctions.
                    var self = this;

                    // Product array from server.
                    self.products = json.products;

                    // Automatic refreshed parameter in UI.
                    self.categoryName = ko.observable(json.categoryName);

                    // Update form parameters.
                    self.productId = null;
                    self.productDescription = null;

                    // Update function.
                    self.update = function () {

                        // Get products collection index.
                        index = self.products.findIndex(function (product) {
                            return product.Id == self.productId
                        });

                        // Throws -1, index was not found !
                        alert(index);

                        // Assign new value.
                        // self.products[index].description(self.productDescription);
                    };
                }

                // Apply viewModel to UI
                ko.applyBindings(new viewModel());

            })();

    </script>

我需要帮助两件事

  1. 更新knockout viewmodel(基于viewModel.Update函数中Id和Description输入的self.products集合)
  2. 更新表格(使用razor foreach时,我不知道如何绑定行)
  3. 编辑:

    当我用Knockout foreach改变Razor循环时

    <tbody data-bind="foreach: products">
            <tr>
                <td data-bind="text: id"></td>
                <td data-bind="text: description"></td>
            </tr>
        </tbody>
    

    它也不起作用:/我尝试使用observables进行一些更改

     <script type='text/javascript'>
    
                // Plain javascript alternative to jQuery.ready.
                (function () {
    
                    // Convert server model to json object.
                    var json = {"products":[{"id":1,"description":"Product A"},{"id":2,"description":"Product B"},{"id":3,"description":"Product C"}],"categoryName":"chocolates"};
    
                    function viewModel()
                    {
                        var index;
    
                        // Store default this to self, to be able use self in subfunctions.
                        var self = this;
    
                        // Product array from server.
                        self.products = ko.observable(json.products);
    
                        // Automatic refreshed parameter in UI.
                        self.categoryName = ko.observable(json.categoryName);
    
                        // Update form parameters.
                        self.productId = ko.observable();
                        self.productDescription = ko.observable();
    
                        // Update function.
                        self.update = function () {
    
                            self.products()[self.productId()-1].description = self.productDescription()    
                        };
                    }
    
                    // Apply viewModel to UI
                    ko.applyBindings(new viewModel());
    
                })();
    
        </script>
    

    我没有收到错误,但是html表中的值没有改变。

1 个答案:

答案 0 :(得分:0)

您的基因剔除代码看起来大部分都是正确的,但是您的UI并未更新,因为您所更改的值是不可观察的。如果您希望对项目所做的更改反映在表中,则需要使每个字段都将更新一个可观察的字段,而不是对整个json对象使用单个可观察的属性。

以下代码仅在整个对象引用更改时才会更新。 IE(如果您使用新对象填充self.products)。如果更改现有对象的属性,它将不会更新。

// Product array from server.
self.products = ko.observable(json.products);

您需要更改代码,以在来自服务器的json对象上分别应用可观察的属性。

// Product array from server.
self.products = ko.observableArray([]); //Changed to array type
for(var i = 0; i < json.products.length; i++){
    self.products.push({
        id: json.products[i].id,
        description: ko.observable(json.products[i].description)
    });
}

然后必须使用函数样式getter / setter更新值。

// Update function.
self.update = function () {
    self.products()[Number(self.productId())-1].description(self.productDescription());
};

  // Convert server model to json object.
  var json = {"products":[{"id":1,"description":"Product A"},{"id":2,"description":"Product B"},{"id":3,"description":"Product C"}],"categoryName":"chocolates"};

  function viewModel()
  {
    var index;

    // Store default this to self, to be able use self in subfunctions.
    var self = this;

    // Product array from server.
    self.products = ko.observableArray([]); //Changed to array type
    for(var i = 0; i < json.products.length; i++){
        self.products.push({
            id: json.products[i].id,
            description: ko.observable(json.products[i].description)
        });
    }

    // Automatic refreshed parameter in UI.
    self.categoryName = ko.observable(json.categoryName);

    // Update form parameters.
    self.productId = ko.observable();
    self.productDescription = ko.observable();

    // Update function.
    // Update function.
    self.update = function () {
        self.products()[Number(self.productId())-1].description(self.productDescription());
    };
    
  }

  // Apply viewModel to UI
  ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<table class="table table-bordered table-striped table-hover">
    <thead>
        <tr>
            <th>Id</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: products">
        <tr>
            <td data-bind="text: id"></td>
            <td data-bind="text: description"></td>
        </tr>
    </tbody>
</table>
<br/>

<label>Id: </label>
<input data-bind="value: productId" type="text" class="form-control" />

<br />

<label>Description: </label>
<input data-bind="value: productDescription" type="text" class="form-control" />

<br />

<button class="btn btn-primary" data-bind="click: update">Update</button>