Best way to handle re-rendering of a view in backbone.js?

I have the following view:

Main.Views.Login = EventQ.View.extend({ events: { "submit form": "login" }, template: "login", login: function(e) { var me = this; $.ajax({ url: "/api/users/login", type: 'POST', dataType: "json", data: $(e.currentTarget).serializeArray(), success: function(data, status){ EventQ.app.router.navigate('dashboard', true); }, error: function(xhr, status, e) { var result = $.parseJSON(xhr.responseText); me.render_with_errors(result.errors); } }); return false; }, render: function(done) { var me = this; // Fetch the template, render it to the View element and call done. EventQ.fetchTemplate(me.template, function(tmpl) { me.el.innerHTML = tmpl(me.model.toJSON()); done(me.el); }); }, render_with_errors: function(errors) { var me = this; // Fetch the template, render it to the View element and call done. EventQ.fetchTemplate(this.template, function(tmpl) { me.el.innerHTML = tmpl(errors); }); } }); 

and a simple template:

 <form> <input name="username" /> <input name="password" /> <button type="submit" /> </form> 

what I want to do is the ability to re-display the template if errors are returned, but keep the filled input. Example error template:

 <form> <input name="username" /> <label class="error">required</label> <input name="password" /> <button type="submit" /> </form> 

Is there a way to bind a view to a model or something that I can verify? Now render_with_errors works, except that I lose all the data that is filled in the form.

+4
source share
2 answers

Itโ€™s common for people to switch to a mode where only they think that the only way to change the page is to completely re-render the template. But creating templates is just one solution to refresh the page. You can still use traditional methods from your main mode. So, another possible solution is to simply adjust the dom from your view.

So make your template as follows:

 <form> <input name="username" /> <label class="error" style="display:none">required</label> <input name="password" /> <button type="submit" /> </form> 

And then make the following change to your login function:

 error: function(xhr, status, e) { var result = $.parseJSON(xhr.responseText); me.showLoginError(); } showLoginError: function() { this.$('.error').show(); } 

And, of course, you can always add to this additional information, message settings, etc.

It is simply important to remember that full template rendering is not the only way for your base code to respond to changes in the state of the application, and to properly manage the DOM in a method other than rendering.

+1
source

Suppose you have a model like this:

 Main.Models.LoginModel = EventQ.Model.extend({ /* ... */ defaults: { 'username': "", 'password': "" }, /* ... */ 

When your success in Ajax-Request, you can go to the next page. If this fails, you can set the model to undefined to indicate a missing value:

 // assumed you did not enter your password this.me.model.set( { 'username': textBoxValueSoFar, 'password': undefined }); 

Then you can create such a template (it will be the same as when loading the first page):

 <form> <input name="username" value="{{username}}" /> {{#unless username}} <label class="error">required</label> {{/unless}} <input name="password" value="{{password}}" /> {{#unless password}} <label class="error">required</label> {{/unless}} </form> 

{{if}} checks if the value is not false, undefined, null, or []. Thus, when loading the first page, this is an empty line and no error message is provided.

For more information see http://handlebarsjs.com/ part with if).

So what you do: you use an empty string to indicate that so far no wrong value has been entered. You use undefined to check if an incorrect value has been entered (in fact, nothing). In your template, you can check this act accordingly.

0
source

Source: https://habr.com/ru/post/1395141/


All Articles