0

私は初めてなknocokout.jsので、ajax呼び出しを使用してデータがバインドされるテーブルがあります。ユーザーが編集ボタンをクリックすると、テーブルの下の同じページにあるフォームに行情報が入力されます。データをデータベースに正常に更新する ajax 呼び出しの後、テーブルに変更された特定のオブジェクトの変更された値を表示できません。リフレッシュすると、新しい値が表示されます。

これが私のhtmlとjsコードです。

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

コード

    function formatCurrency(value) {
        return "$" + parseFloat(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;
        });


        // 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) {
                      console.log(data.d);                        
                      self.Product(null);

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

        }



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

        }
    }

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

そして、ajaxリクエストによって呼び出された私のwebmethodは次のとおりです:

// to update product
    [WebMethod]
    public static testModel.Product Update(testModel.Product Product)
    {
        testEntities db = new testEntities();
        var obj = db.Products.First(o => o.Id == Product.Id);
        obj.Name = Product.Name;
        obj.Price = Product.Price;
        obj.Category = Product.Category;

        db.SaveChanges();


        return obj;
    }

次のような ajax 呼び出しの JSON 応答

{"d":{"__type":"testModel.Product","Id":31,"Name":"12","Category":"12","Price":1350,"EntityState":2,"EntityKey":
{"EntitySetName":"Products","EntityContainerName":"testEntities","EntityKeyValues":
[{"Key":"Id","Value":31}],"IsTemporary":false}}}
4

3 に答える 3

0

変更するものがあります:

交換

$.each(data.d, function (index, prd) {
     self.Products.push(prd);
 })

と:

$.each(data.d, function (index, prd) {
     self.Products.push({
                    Id: ko.observable(prd.Id),
                    Name: ko.observable(prd.Name),
                    Price: ko.observable(prd.Price),
                    Category: ko.observable(prd.Category)
                });
})

ko.observableビューがそれに応じて更新できるように、プロパティにその変更をビューに通知させるために使用します。これは機能するはずですが、完全ではありません。これは 2 方向バインディングであるためです。そのため、 の値を更新するたびdivに、ビュー モデル オブジェクトがすぐに更新され、ajax がバックエンドでデータの更新に失敗した場合でも、クライアント間のデータが同期しなくなります。サイドとサーバーサイド。

より良い解決のために。protectedObservableを見る必要があります

$.each(data.d, function (index, prd) {
         self.Products.push({
                        Id: ko.protectedObservable(prd.Id),
                        Name: ko.protectedObservable(prd.Name),
                        Price: ko.protectedObservable(prd.Price),
                        Category: ko.protectedObservable(prd.Category)
                    });
    })

self.updateajax 成功関数内で、変更をトリガーします。

success: function (data) {
    var product =self.Product();   
    product.Id.commit();
    product.Name.commit();
    product.Price.commit();
    product.Category.commit();     
    self.Product(null);

    alert("Record Updated Successfully");
}

エラーがある場合は元に戻します。

error: function (data) {
    product.Id.reset();
    product.Name.reset();
    product.Price.reset();
    product.Category.reset(); 
 }

更新:プロパティ値を取得するにはProduct.Propertyto に変更することを忘れないでくださいProduct.Property()例: arr[i].Priceに変更する必要がありますarr[i].Price()

于 2013-09-05T09:25:09.403 に答える
-1

関数ハンドラに追加self.Products.push(data.d);します。update()success

success: function (data) {
     console.log(data.d);                        
     self.Product(null);

     self.Products.push(data.d);

     alert("Record Updated Successfully");
},

バインドされた html に反映されるように、配列を更新する必要があります。

于 2013-09-05T09:26:21.130 に答える