Knockoutjs - With bindings and state

Viewed 129

I'm having an issue with component binding and state.

This is my html template:

<div class="ts-panel content">
<!--ko with: states.createState-->
<div data-bind="component: 'customer-create'">Testing CreateState</div>
<!--/ko-->
<!--ko with: states.lookupState-->
<div data-bind="component: 'customer-search'">Testing LookupState</div>
<!--/ko-->
</div>

This is my javascript

var myDataModel = function () {
    var self = this;
    self.states = {};
    self.states.createState = ko.observable(true);
    self.states.lookupState = ko.observable(false);
    self.states.currentState = ko.observable(self.states.createState);
    self.states.changeState = function (state) {
    var currentState = self.states.currentState();
        currentState(false);
        self.states.currentState(state);
        state(true);
    }
};
return myDataModel;

I'm using another script to control which state I'm in by binding click events to certain buttons.

The problem I'm running into is that when I change the current state, the component bindings reset the state of the component. Eg. on the customer-create component, I fill out a form, then change to the lookupState, then change back to the createState, the form values are gone.

I think this is happening because the components are getting wiped out and recreated every time.

I also think that one solution to this is to store everything at the root level (i.e. the component that stores the states) and pass that all down when required to the individual components. However, I'd really like to keep the component-specific information inside those components.

Is there a way to store the state of the components or maybe store the components in a variable and bind to it that way?

1 Answers

From the documentations:

If the expression you supply involves any observable values, the expression will be re-evaluated whenever any of those observables change. The descendant elements will be cleared out, and a new copy of the markup will be added to your document and bound in the context of the new value.

The behaviour is same for the if binding as well. You could use the visible binding for this. This just hides and shows the div without actually removing it from the DOM. There is no containerless control flow syntax for visible. So, you'd have to add it to the div

<div data-bind="component:'customer-create', visible: states.createState">Testing CreateState</div>
Related