0
votes

I am using knockout for data binding on a form contained on a modal. Once the user submits the form, the modal closes on a successful post. I would also like to clear all the observable values from my knockout view model so the user can open the modal and submit a new form from scratch. I do not want to lose the ko.observable bindings that are already set on the fields.

For context, my viewmodel is a child of another view model.

In my parent view model

self.childElement = ko.observable(new childElementVm());

my child view model

var childElementVm = function (){
    var self= this;
    self.property1 = ko.observable()
    self.property2 = ko.observable()
    self.property3 = ko.observable()
    self.property4 = ko.observable()
    self.property5 = ko.observable()
    self.property6 = ko.observable()
    self.array1 = ko.observableArray()
    self.array2 = ko.observableArray()
    self.array3 = ko.observableArray()
    self.array4 = ko.observableArray()

    //several more observables

    //a smattering of functions including some self.property.subscribe functions

    $.ajax({
         //post
    }).done(function(){
        $('#myModal').modal('hide');
        //reset all values in childElementVm
    });
}
4
How complex is childElementVm? Can you show its source?Steve Danner
it is not incredibly complex, has some ajax calls and some subscribes, i added a few properties to my example but probably only about a quarter of the total observablesUSER_8675309

4 Answers

4
votes

It might be better to create a new view model each time. You use Knockout to destroy and remake your view model. The if binding will add and remove elements from the dom. If the element added is a Knockout component, it's view model will be created automatically.

<div class="myModal">
    <-- ko if: isModalPresented -->
        <my-child-component params="myChildElementParams"></my-child-component>
    <-- /ko -->
</div>
2
votes

You can use this function:

function resetObservables(object, defaultValue) {
    for (var key in object) {
        if (object.hasOwnProperty(key)) {
            var property = object[key];
            if(ko.isObservable(property)){
                property(defaultValue);
            }
        }
    }
}

In this way :

$.ajax({
     //post
}).done(function(){
    $('#myModal').modal('hide');
    //reset all values in childElementVm
    resetObservables(self,"");
});
1
votes

You could put in a new viewmodel every time you open your modal, so on opening the modal do something like this:

parentVM().childElementVm(new childElementVm());

I saw in the comments you have some subscribes in your childElementVm, so if you do the following, you'll have to store the subscriptions inside childElementVm and dispose of them when closing the modal. This would look a bit like this:

//Store subscriptions
var subscriptions = [];
subscriptions.push(myViewModel.personName.subscribe(function(newValue) {
    alert("The person's new name is " + newValue);
}));

//Dispose
for(var i = 0; i < subscriptions.length; i++){
    subscriptions[i].dispose()
}

This will reset your data since there's a brand new childElementVm every single time you open your modal.

0
votes

to clean an observable just use:

self.property1('');