This is my first time working with Knockback.js.
I'm working on a Knockback proof of concept, but I'm having a hard time getting the view model to update when I save a model. In this case, what happens is the server returns a new Domain
object with the id
field set, which means that the object now exists on the backend. Once that happens, I would like the UI to change to reflect the fact that it is now saved.
Here is the code I'm using:
<table cellspacing="0" class="listing-table" id="domainListTable">
<thead>
<tr>
<th scope="col">
Domain
</th>
</tr>
</thead>
<tbody data-bind="foreach: domains">
<tr>
<td>
<!-- ko if:save -->
<a data-bind="attr: { href: domainEditLinkdomainId, title: domain},text : domain">
<span data-bind="text: domain"></span>
</a>
<!-- /ko -->
<!-- ko ifnot:save -->
<input type="text" maxlength="250" style="display:inline-block;" class="medium-text-field" data-bind="value: domain"></input>
<input data-bind="click: save" style="display:inline-block;" type="submit" value="Save New Domain" alt="" title=""/>
<!-- /ko -->
</td>
</tr>
</tbody>
</table>
<br />
<input data-bind="click: addDomain" type="submit" value="Add New Domain" alt="" title=""/>
<script type="text/javascript">
var Domain = Backbone.Model.extend({
defaults: function() {
return {
domain: "New Domain"
};
},
});
var Domains = {};
Domains.Collection = Backbone.Collection.extend({
model: Domain,
url: '/cms/rest/poc/${customerId}/domains/'
});
var domains = new Domains.Collection();
domains.fetch();
var DomainViewModel = kb.ViewModel.extend({
constructor: function(model) {
kb.ViewModel.prototype.constructor.apply(this, arguments);
var self = this;
this.save = kb.observable(model, {
key: 'save',
read: (function() {
return !model.isNew();
}),
write: (function(completed) {
return model.save({}, {
wait: true,
success: function (model, response) {
console.log(model);
console.log(response);
console.log(self);
},
error: function(model, response) {
alert("Oh NooooOOOes you broked it!!!11!")
}
});
})
}, this);
this.domainEditLinkdomainId = ko.dependentObservable(function() {
if(!this.save())
return "";
return "cms?action=domainDetail&domainID=" + this.model().id;
}, this);
}
});
var DomainsViewModel = function(collection) {
this.domains = kb.collectionObservable(collection, { view_model: DomainViewModel });
this.addDomain = function() {
this.domains.push(new DomainViewModel(new Domain()));
};
};
var domainsViewModel = new DomainsViewModel(domains);
ko.applyBindings(domainsViewModel);
</script>
The problem seems to be that the XMLHttpRequest
done by model.save()
does not return until after the save kb.observable
is read, and so the html part does not update successfully, since it still sees model.isNew()
as true.
I've been messing around with a couple of different ideas, as you can probably see, including using the valueHasMutated
method on an observable to indicate that the model has been updated, but I can't figure out how to do that either.
Any help would be greatly appreciated!