Hi i've got a durandal app that send data trought ajax but i dont know how to implement the loading indicator , here is the codes:
this is the view that loads the data loadinbox.html
<div class="modal-content messageBox">
<div class="modal-header">
<h3>LOGIN</h3>
</div>
<div class="modal-body">
<h3>Entre com suas credenciais.</h3>
<form data-bind="submit: ok">
<input type="text" data-bind="value: login" placeholder="CPF" class="form-control autofocus" />
<input type="text" data-bind="value: senha" placeholder="Senha" class="form-control autofocus" />
</form>
</div>
<div data-bind="if: $parent.loading">
<img src="img/loading.gif"/>
</div>
<div class="modal-footer">
<button class="btn btn-success" data-bind="click: ok, active: $parent.loading">Login</button>
</div>
</div>
this is the model that loads the data loginBox.js
define(function (require) {
var dialog = require('plugins/dialog');
var loading = ko.observable();
var loginBox = function(){
this.login = '';
this.senha = '';
this.loading = false;
};
loginBox.prototype.ok = function () {
this.loading =true;
$.ajax({
type: "post",
data: { "LoginForm[cpf]" : this.login, "LoginForm[password]" : this.senha , 'ajax':'login-form' },
url: localStorage['baseurl']+localStorage['router']+'site/login',
success: function (data){
console.log(data);
},
error: function (request, status, error){
console.log(request.status);
console.log(status);
console.log(error);
},
complete: function (data) {
alert('hqweuiqhioehqio');
this.loading =false;
}
});
};
loginBox.show = function() {
return dialog.show(new loginBox());
};
return loginBox;
});
On the surface, your approach is sound, but your approach to modules in Durandal is a little muddled. For example, you've declared
loading
twice, once as a scalar and once as an observable.So, let's create an instance module (which means that we're going to return a constructor function):
loginBox.html (view)
Notice that I changed your
if
binding to this:referencing
loading
with parentheses. This performs an immediate eval using the default value supplied to the observable, and then a re-eval when the observable changes.Also, it may be necessary to change
"click: ok, active: $parent.loading()"
toclick: $parent.ok.bind($parent), active: $parent.loading()
. Check your context using the debugger when the #ok function is entered.A note on logic: It seems to me that what you might mean in the modal footer is
Should the OK button really be active when the form is loading data?
loginBox.js (module instance approach)
Take note of my treatment of
this.loading
. It is an observable, and observables are updated using the approach I show above (remember, they are functions). When you assigntrue
in this manner--this.loading = true
--you override the observable itself and turn it into a non-observable scalar. So, when the value later changes (from false to true to false), the view is not updated.Also note that you must import KnockoutJS.
Another issue: you have a
this
reference issue in your #complete function. Note that I do this at the top of your #Ok function:and, then, in your #complete function, I do this:
Using
this
in your #complete function references the #complete function itself, not the viewModel. We have to save a reference tothis
outside the #complete function.There was another problem: #show was not on the prototype.