sgireddy
sgireddy

Reputation: 185

KoGrid JSON Dynamic widgets

I am working on a dashboard where I am using KOGrid, my idea is to dynamically create a bunch of widgets and bind data into the kogrid for each widget. The problem is with knockout binding, I am using myObsArray when I create the DIV dynamically, and using the same in the view model, this is causing all widgets to be bound to the same data (i.e. as it is observable, overriding the data for the last widget for all widgets). All my attempts to fix this via associative arrays are futile. You help is greatly appreciated. Thanks a million in advance.

I have two controllers (MVC4), where the fist returns a list of widget names and the second returns results (datatable) in JSON format. I am using JSON.Net JsonConvert to convert the results to json format then passing as JSON content result. All is well when I use one widget but the issue is when using more than one widget.

function loadWidgets(data) {
        //showLoading();
        var div1 = $("#db-col-1");
        var div2 = $("#db-col-2");
        div1.html('');
        div2.html('');
        $.each(data, function (index, item) {

            var li = "<li id='" + item.WIDGET_NAME + "_li'></li>";
            if (index % 2 == 0)
                div1.append(li);
            else
                div2.append(li);

            $("#" + item.WIDGET_NAME + "_li")
            .append("<div id= '" + item.WIDGET_NAME + "' class='example' data-      bind='koGrid: { data: myObsArray }'></div>"); //,
            LoadJson(item.WIDGET_NAME, item.WIDGET_NAME + "Arr" );

        });
    }


   function LoadJson(widgetName) {
        var wName = widgetName;
        $.getJSON('Home/GetWidgetDetails?widgetName=' + wName, 
            function (data) {
                window.viewModel = {
                        myObsArray: ko.observableArray(data) //myObsArray
                    };                                                                  
                    ko.applyBindings(viewModel);
                });        
    }

Thanks, shashi

Upvotes: 1

Views: 868

Answers (1)

Kyeotic
Kyeotic

Reputation: 19857

First, do not call ko.applyBindings in a function that can be called more than once. This call should only ever happen once per viewmodel. This has come up a lot lately, I am starting to think someone has done this in a bad tutorial somewhere.

Second, your problem is that you are overwriting your viewmodel. This bit here:

window.viewModel = {
    myObsArray: ko.observableArray(data) //myObsArray
};

The first time this is called, it creates your viewmodel. The second+ times, it OVERWRITES your viewmodel. Furthermore, creating your HTML programatically is unnecessary. Knockout is better suited to this task with a foreach binding. You seem to be missing a lot of what knockout is supposed to be for, so I would encourage you to go through the tutorials, if you haven't done so. Lastly, your HTML is going to be invalid. You are making li nodes without a ol or ul to put them in.

Here is an MVVM solution to your problem, in a fiddle. It is simplified to demonstrate binding concepts, and doesn't use koGrid.

Upvotes: 1

Related Questions