Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout refresh viewModel using mapping plugin

I am trying refresh a small widget with knockout and the mapping plugin. Here is my code so far:

var AppViewModel = function (data, total, qty) {
    var self = this;
    self.Products = ko.mapping.fromJS(data, {}, this);
    self.CartTotals = ko.observable(total);
    self.TotalQty = ko.observable(qty);
};

var func = function(u) {
    return $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", data: "{}", dataType: "json", url: u });
},
getQtyTotal = function(b) {
    var a = 0;
    $.each(b.Table.Rows, function(c) {
        a += parseInt(b.Table.Rows[c].Quantity) || 0;
    });
    return a;
};

$.when(func("/store/MiniCart.aspx/GetShoppingCartInfo"), func("/store/MiniCart.aspx/GetCartTotal")).done(function (jsonA, jsonB) {
    var ds = $.parseJSON(jsonA[0].d), ds2 = $.parseJSON(jsonB[0].d), qtyTotal = getQtyTotal(ds);
    ko.applyBindings(new AppViewModel(ds, ds2, qtyTotal));
});

<div class="cartDropDownProductItemWrapper" data-bind="foreach: Products.Table.Rows">
    <div class="cartDropDownProductItem">
        <div class="cartDropDownProductImg">
            <img id="cart_details_rpt_prod_image_0" style="height: 71px; width: 55px;" data-bind="attr: { src: ProductImageURL }">
        </div>

        <div class="cartDropDownProductDesc">
            <h6><a data-bind="text: ModelName, attr: { href: ProductLink }"></a></h6>
            <div class="cartDropDownProductDescInner">
            <div class="cartDropDownColor"> COLOR 
                <strong><span data-bind="text:ColorName"></span></strong>
            </div>
            <div class="cartDropDownSize"> SIZE
                <strong><span data-bind="text: SizeName"></span></strong>
            </div>
            <div class="cartDropDownSize"> QTY 
                <strong><span data-bind="text: Quantity"></span></strong>
            </div>
            <div class="cartDropDownPrice"> PRICE 
                <strong><span data-bind="text: UnitCost().toFixed(2)"></span></strong>
            </div>
            <div class="cartDropDownRemove">
                <a href="javascript:void(0);" class="remove" onclick="removeItem('v3BuhngpE4c=')">
                    <img src="/images/layout/icons/remove.gif" alt="Remove Item">
                </a>
            </div>
        </div>
    </div>
    <div class="clear"></div>
</div>


<!-- end fo reach -->
<div class="clear"></div>
<div class="cartDropDownButtons clearfix">
    <ul class="clearfix">
        <li class="countItems"><span data-bind="text: TotalQty"></span> Items</li>
        <li class="subTotal" id="subTotal">SUBTOTAL: $<span data-bind="text: CartTotals().toFixed(2)"></span></li>
    </ul>
</div>

It renders fine intially but when I try to rebind on a jQuery click event and call:

   ko.applyBindings(new AppViewModel(ds, ds2, qtyTotal));

It duplicates the data.

like image 868
user1933368 Avatar asked Feb 28 '26 03:02

user1933368


1 Answers

If you start off by creating an empty viewModel... which takes no arguments via it's constructor, like so:

function ViewModel()
{
    var self = this;
}
var viewModel = new ViewModel();

...Then you can reference it by name to load in your data using ko.mapping, like this:

ko.mapping.fromJS({ "PropertyName": plainJsObject }, {}, viewModel);

What this does is runs the ko.mapping magic on plainJsObject, and stuffs the result into a property (in this case, called PropertyName) on your viewModel object.

The part you would particularly care about is this:

If you want to refresh the data located in the viewModel.PropertyName with fresh data from the server... you just call the exact same method, and it updates that same property on your viewModel. Just call this same thing again, with new values in your plainJsObject:

ko.mapping.fromJS({ "PropertyName": plainJsObject }, {}, viewModel);

Since you have (I assume) already performed your ko.applyBindings() at some point in your code, this line above will immediately update your view.

like image 195
ClearCloud8 Avatar answered Mar 02 '26 21:03

ClearCloud8



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!