使用ajax在post请求后不更新viewmodel中的实体

时间:2013-09-04 08:43:17

标签: asp.net knockout.js

我是knockout.js的新手,我正在使用post方法将数据更新到数据库中。这是我的代码

 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="SProduct.aspx.cs" Inherits="SProduct" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script src="http://knockoutjs.com/downloads/knockout-2.2.1.js" type="text/javascript"></script>
</head>
<body>
    <form id="form1" runat="server">
    <div id="body">
        <h2>
            Knockout CRUD Operations with ASP.Net Form App</h2>
        <h3>
            List of Products</h3>
        <table id="products1">
            <thead>
                <tr>
                    <th>
                        ID
                    </th>
                    <th>
                        Name
                    </th>
                    <th>
                        Category
                    </th>
                    <th>
                        Price
                    </th>
                    <th>
                        Actions
                    </th>
                </tr>
            </thead>
            <tbody data-bind="foreach: Products">
                <tr>
                    <td data-bind="text: Id">
                    </td>
                    <td data-bind="text: Name">
                    </td>
                    <td data-bind="text: Category">
                    </td>
                    <td data-bind="text: formatCurrency(Price)">
                    </td>
                    <td>
                        <button data-bind="click: $root.edit">
                            Edit</button>
                        <button data-bind="click: $root.delete">
                            Delete</button>
                    </td>
                </tr>
            </tbody>
            <tfoot>
                <tr>
                    <td>
                    </td>
                    <td>
                    </td>
                    <td>
                        Total :
                    </td>
                    <td data-bind="text: formatCurrency($root.Total())">
                    </td>
                    <td>
                    </td>
                </tr>
            </tfoot>
        </table>
        <br />
        <div style="border-top: solid 2px #282828; width: 430px; height: 10px">
        </div>
        <div data-bind="if: Product">
            <div>
                <h2>
                    Update Product</h2>
            </div>
            <div>
                <label for="productId" data-bind="visible: false">
                    ID</label>
                <label data-bind="text: Product().Id, visible: false">
                </label>
            </div>
            <div>
                <label for="name">
                    Name</label>
                <input data-bind="value: Product().Name" type="text" title="Name" />
            </div>
            <div>
                <label for="category">
                    Category</label>
                <input data-bind="value: Product().Category" type="text" title="Category" />
            </div>
            <div>
                <label for="price">
                    Price</label>
                <input data-bind="value: Product().Price" type="text" title="Price" />
            </div>
            <br />
            <div>
                <button data-bind="click: $root.update">
                    Update</button>
                <button data-bind="click: $root.cancel">
                    Cancel</button>
            </div>
        </div>
        <div data-bind="ifnot: Product()">
            <div>
                <h2>
                    Add New Product</h2>
            </div>
            <div>
                <label for="name">
                    Name</label>
                <input data-bind="value: $root.Name" type="text" title="Name" />
            </div>
            <div>
                <label for="category">
                    Category</label>
                <input data-bind="value: $root.Category" type="text" title="Category" />
            </div>
            <div>
                <label for="price">
                    Price</label>
                <input data-bind="value: $root.Price" type="text" title="Price" />
            </div>
            <br />
            <div>
                <button data-bind="click: $root.create">
                    Save</button>
                <button data-bind="click: $root.reset">
                    Reset</button>
            </div>
        </div>
    </div>
    <script type="text/javascript">

        function formatCurrency(value) {
            return "$" + value.toFixed(2);
        }

        function ProductViewModel() {

            //Make the self as 'this' reference
            var self = this;
            //Declare observable which will be bind with UI 
            self.Id = ko.observable("");
            self.Name = ko.observable("");
            self.Price = ko.observable("");
            self.Category = ko.observable("");

            var Product = {
                Id: self.Id,
                Name: self.Name,
                Price: self.Price,
                Category: self.Category
            };

            self.Product = ko.observable();
            self.Products = ko.observableArray(); // Contains the list of products

            // Initialize the view-model
            $.ajax({
                url: 'SProduct.aspx/GetAllProducts',
                cache: false,
                type: 'POST',
                contentType: 'application/json; charset=utf-8',
                data: {},
                success: function (data) {
                    // debugger;

                    $.each(data.d, function (index, prd) {

                        self.Products.push(prd);
                    })
                    //Put the response in ObservableArray
                }
            });

            // Calculate Total of Price After Initialization
            self.Total = ko.computed(function () {
                var sum = 0;
                var arr = self.Products();
                for (var i = 0; i < arr.length; i++) {
                    sum += arr[i].Price;
                }
                return sum;
            });

            //Add New Item
            self.create = function () {
            Product.Id="333";
                if (Product.Name() != "" && Product.Price() != "" && Product.Category() != "") {

                    $.ajax({
                        url: 'SProduct.aspx/Add',
                        cache: false,
                        type: 'POST',
                        contentType: 'application/json; charset=utf-8',
                        data:"{item:" + ko.toJSON(Product) + "}",
                        success: function (data) {
                                 self.Products.push(data.d);


                            self.Name("");
                            self.Price("");
                            self.Category("");

                        },
                        error:function(data)
                        {
                        alert("error");
                        console.log(data.d);
                        }
                    });

                }
                else {
                    alert('Please Enter All the Values !!');
                }

            }
                         //Delete product details
                         self.delete = function (Product) {
                         if (confirm('Are you sure to Delete "' + Product.Name + '" product ??')) {
                         var id = Product.Id;

                         $.ajax({
                         url:  'SProduct.aspx/Delete',
                         cache: false,
                         type: 'POST',
                         contentType: 'application/json; charset=utf-8',
                         data:"{id:" +  ko.toJSON(id) + "}",
                         success: function (data) {
                         self.Products.remove(Product);

                         },
                         error:function(data){
                         console.log(data.d);
                        alert('Error');
                         }
                         })
                         }
              }

            // Edit product details
            self.edit = function (Product) {
                self.Product(Product);

            }

            // Update product details
            self.update = function () {
                var Product = self.Product();

                $.ajax({
                    url: 'SProduct.aspx/Update',
                    cache: false,
                    type: 'POST',
                    contentType: 'application/json; charset=utf-8',
                    data:"{Product:" +  ko.toJSON(Product) + "}", 
                    success: function (data) {
                        alert("success");
                        console.log(data.d);

//                        self.Products.removeAll();
                        //   self.Products(data.d); //Put the response in ObservableArray

                        self.Product(null);

                        alert("Record Updated Successfully");
                    },
                    error: function (data) {
                        console.log(data);
                    }
                })

            }

            // Reset product details
            self.reset = function () {
                self.Name("");
                self.Price("");
                self.Category("");
            }

            // Cancel product details
            self.cancel = function () {
                self.Product(null);

            }
        }
        var viewModel = new ProductViewModel();
        ko.applyBindings(viewModel);

    </script>
    </form>
</body>
</html>

更新 enter image description here 这是我的页面的屏幕截图。当我点击更新ajax成功函数被调用,但上面的表字段没有变化。

1 个答案:

答案 0 :(得分:2)

为什么必须将项目更新回列表?你没有对服务器端对象的属性做任何事情吗?

您的编辑方法应如下所示:

    self.edit = function(item) {
        self.Product(item);

    };

并删除以下代码nemesv说。

   self.Products.removeAll();
   self.Products(data.d); //Put the response in ObservableArray

我的第一篇帖子很温柔;)

对评论的回应:

将您的成功转变为:

    success: function (data) {
          var product = ko.utils.arrayFirst(self.Products(), function(item) {
               return (item.Id == data.d.Id);       
          });  // You could either update the product object with the new values from data.d or delete it and add a new product object.
          for (var p in product ) {
                product [p] = data.d[p];
          } 

          self.Product(null);
          alert("Record Updated Successfully");
    },

发现了一个错误,它正在用原生值替换observable。

          for (var p in product ) {
                product [p](data.d[p]);
          } 

我冒昧地简化了代码并删除了与更新功能无关的所有内容。以下代码示例应该有效。 (我使用了淘汰赛2.3.0和jQuery 1.9.1)

    <script type="text/javascript">

    function Product(id, name, price, category) {
        var self = this;
        self.Id = ko.observable(id);
        self.Name = ko.observable(name);
        self.Price = ko.observable(price);
        self.Category = ko.observable(category);
    }

    function ProductViewModel() {

        var self = this;
        self.Product = ko.observable();
        self.Products = ko.observableArray(); // Contains the list of products

        $.ajax({
            url: 'SProduct.aspx/GetAllProducts',
            cache: false,
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            data: {},
            success: function (data) {
                $.each(data.d, function (index, prd) {
                    var p = new Product(prd.Id, prd.Name, prd.Price, prd.Category);
                    self.Products.push(p);
                });
            }
        });

        self.Total = ko.computed(function () {
            var sum = 0;
            var arr = self.Products();
            for (var i = 0; i < arr.length; i++) {
                sum += arr[i].Price;
            }
            return sum;
        });

        self.edit = function(product) {
            self.Product(product);
        };

        self.update = function() {
            var product = self.Product();
            $.ajax({
                url: 'SProduct.aspx/Update',
                cache: false,
                type: 'POST',
                contentType: 'application/json; charset=utf-8',
                data: "{product:" + ko.toJSON(product) + "}",
                success: function (data) {
                    for (var p in product) {
                        product[p](data.d[p]);
                    }
                    self.Product(null);
                    alert("Record Updated Successfully");
                },
                error: function(data) {
                    console.log(data);
                }
            });
        };

        self.reset = function() {
            self.Name("");
            self.Price("");
            self.Category("");
        };

        self.cancel = function() {
            self.Product(null);

        };
    }

    $(document).ready(function() {
        var viewModel = new ProductViewModel();
        ko.applyBindings(viewModel);
    });


</script>