Sruj
Sruj

Reputation: 1207

How to update data used by kendo.observable object using ajax? Kendo UI

Is it possible to affect data asynchronicaly (ajax) that is used by kendo.observable object in Kendo UI?

With below code cart.add() function is triggered and cart.contents variable is updated, but this not affect the template and not refreshing data used by template. I'm expecting that changing cart.contents changes data used by template, like text: quantity and text: itemPrice

template script 1:

<script type="text/x-kendo-template" id="cart-preview-template">
  <div id="shop-info" data-bind="attr: { class: cartContentsClass }">
    <ul data-role="listview" data-bind="source: cart.contents" data-template="cart-item" id="shop-list"></ul>
        <div id="shopping-cart">
            <p class="total-price" data-bind="html: totalPrice"></p>
            <a id="empty-cart" href="#" data-bind="click: emptyCart">empty cart</a>
        </div>
    </div>
</script>

template script 2:

<script type="text/x-kendo-template" id="cart-item">
    <li class="selected-products-list">
        <a data-bind="click: removeFromCart" class="view-selected-items">
            <img data-bind="attr: { src: imageSource, alt: imageAlt }"
            />
        </a>
            <span data-bind="text: quantity"></span>
            <span data-bind="text: itemPrice"></span>
        </span>
    </li>
</script>

model:

var cartPreviewModel = kendo.observable({
                cart: cart,

                cartContentsClass: function () {
                    return this.cart.contentsCount() > 0 ? "active" : "empty";
                },

                removeFromCart: function (e) {
                    this.get("cart").remove(e.data);
                },

                emptyCart: function () {
                    cart.empty();
                },

                itemPrice: function (cartItem) {
                    return kendo.format("{0:c}", cartItem.item.unitPrice);
                },

                imageSource: function (cartItem) {
                    var baseUrl = "{{ absolute_url(asset('images/products/')) }}";
                    return baseUrl + cartItem.item.image;
                },

                imageAlt: function () {
                    return "Product image";
                },

                totalPrice: function () {
                    return this.get("cart").total();
                },

                proceed: function (e) {
                    this.get("cart").clear();
                    sushi.navigate("/");
                }
            });

object observable cart used by:

        var cart = kendo.observable({
            //for testing purpose, just to show cart panel bar at start with some items. 
            //originally it should be: contents: []
            contents: [{"item":"productID":1,"unitPrice":"111.00","image":"5.jpg"},"quantity":1}],
            add: function (item) {
                $.ajax({
                    type: 'POST',
                    url: '{{ path('add_product') }}',
                    dataType: 'json',
                    data: {'item': JSON.stringify(item)},
                    success: function (sessionCart) {
                        // original code: 
                        // this.contents = sessionCart;

                        // code for testing, just to be sure new data is set:
                        this.contents = [{"item":{"productID":1,"unitPrice":"111.00","image":"5.jpg"},"quantity":1},{"item":{"productID":2,"unitPrice":"999.00","image":"8.jpg"},"quantity":1}];
                    },
                });

            },

binding model and template:

kendo.bind($("#shop-info"), cartPreviewModel);

Once again, With above code cart.add() function is triggered and cart.contents variable is updated (while debbuging) but this not affect the template and not refreshing data used by template.

Upvotes: 1

Views: 1217

Answers (1)

NigelK
NigelK

Reputation: 8490

You must use the set() function to change property values on an observable in order to trigger any bindings to update.

So change this:

this.contents = [
  {"item":{"productID":1,"unitPrice":"111.00","image":"5.jpg"},"quantity":1},
  {"item":{"productID":2,"unitPrice":"999.00","image":"8.jpg"},"quantity":1}
];

to this:

this.set("contents", [
   {"item":{"productID":1,"unitPrice":"111.00","image":"5.jpg"},"quantity":1},
   {"item":{"productID":2,"unitPrice":"999.00","image":"8.jpg"},"quantity":1}
]);

Upvotes: 3

Related Questions