TH1976
TH1976

Reputation: 11

Conditional Binding with knockout.js/mapping plugin/koExternal template engine /json from ajax

I made a solution for a single page application, which will be used for a Large Screen display in a factory building, displaying status information and performance indicators for a set of machines. Via a settingsfile, which is derived via an ajax call the application knows which machines with which information should be displayed. So for every machine a template, and for each machine information a nested template is rendered(koExternaltemplateengine). Also the first ajax call contains the urls for the ajax calls for all machines. The respondes of these calls contain the machine-specific values. These calls are repeated periodically and the display values are refreshed. All bindings are made with knockout and the mapping plugin to avoid having a hardcoded viewmodel clientside. The frame and the machine containers(panes) are bound to the data from the first call, the nested templates data-fields are bound to data attributes contained in the machine specific ajax calls response.

Now my problem: If all ajax-calls for all machines deliver the required data for the display, everything works fine. BUT: For some machines, at sometimes(also on initial load), the calls are successfull (200) but contain just null (cause at this moment the data is not available). Now I got the problem. After ko.applybindings(machinedata, machinediv) I got the ' Unable to parse bindings.' for the bound value fields and ko terminates binding. So the display is not rendered complete and no updates are triggered.

Now I will try something with the if/ifnot-bindings, but what happens if after a refresh the initial not bound values are present? (manually retrigger applybindings, additional to ko.mapping.fromJS??).

Did somebody have a similar problem? Any suggestions? As I mentioned I want to avoid hardcoded viewmodels to facilitate future extensions for more machine attributes.

Upvotes: 1

Views: 487

Answers (1)

delixfe
delixfe

Reputation: 2491

You could store your machinedata in an observable:

Your view:

<div data-bind="if: machinedata()>
   <div data-bind="with: machinedata()">
      ...
   </div>
</div>
<div data-bind="if: machinedata()>
   Data could not be loaded....
</div>

The view model:

var ViewModel = function () {
    var self = this;

    self.machinedata = ko.observable();

    self.update = function () {
        var data = someAjaxCall(); // returns the data or any falsy value
        self.machinedata(data);
    };
}

var viewModel = new ViewModel();
ko.applyBinding(viewModel);  // data does not yet exist
viewModel.update();

As long as you only bound the loaded data and did not need any computeds you even would not need ko.mapping.

Upvotes: 0

Related Questions