Reviewing the view results in loss of focus

I continue to face this problem again and again. I have an input view and I want to set and update things on every keyUp event. The problem is that set is caused by triggering a change event that re-displays the view, which causes the input to lose focus. Therefore, after the user types one character, the input loses focus, and they can no longer print.

Another case where this happens is when the user presses input. I want to add a class to the div around the input so that it changes color. This, of course, causes the view to re-render and the input loses focus. I cannot just make a separate view for input because the input is inside the div that I want to redisplay.

Here is a simple example.

itemView = Backbone.View.extend({ events: { "keyup .itemInput": "inputKeyUp" } initialize: function(){ this.model.view = this; this.bind('change', this.render()); this.render(); }, render: function(){ $(this.el).html( $(ich.itemView( this.model.toJSON() )) ); return this; }, inputKeyUp: function(e) { this.model.set({name: $(this.view.el).find('input[type=text]').first().val()}); }, }); 

So far I have circumvented this by using {silent: true} and updating things manually, but this creates a mess.

+6
source share
1 answer

Basically, you end up in some kind of endless loop, where you tie your opinion too much to your model, and they return to each other.

When the user enters text input in the browser, they are already "updating the view." The view already represents additional text.

So, when you update the model with these changes, you do not need to look at the AGAIN update, since it already represents the current state.

So, in these cases, you really want to use "silent", because you just synchronize the model with the current state of the user interface and do not need a model to inform you about the need for updates.

Regarding how often to do this, I suspect there are probably too many on the keyboard. You may want to do this to blur or even “save” some action.

As for the other issue, I'm not sure why adding a class to an element will cause re-rendering. You just do something like

 this.$('input[type="text"]').addClass('active') 

This should not trigger a model change event and run the render again.

Leave a comment:

Then you need to get more details.

In terms of rendering, break individual rendering / updating of presentation elements into separate functions.

Link property-specific property change events ("change: name") for these more granular rendering functions so that they update the part of the view that you want to change but do not update the text input.

 itemView = Backbone.View.extend({ events: { "keyup .itemInput": "inputKeyUp" } initialize: function(){ this.model.view = this; this.bind('change:name', this.update_other_stuff()); this.bind('change:selected', this.add_class()); this.render(); }, update_other_stuff: function(){ this.$('.some_other_thing').html("some desired change"); return this; }, add_class: function(){ this.$('input[type=text]').first().addClass('active'); return this; }, render: function(){ $(this.el).html( $(ich.itemView( this.model.toJSON() )) ); return this; }, inputKeyUp: function(e) { this.model.set({name: $(this.view.el).find('input[type=text]').first().val()}); }, }); 
+3
source

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


All Articles