0

From the Backbone.js (1.2.3) documentation:

add collection.add(models, [options])

Add a model (or an array of models) to the collection, firing an "add" event for each model, and an "update" event afterwards.

In my code I want to add a new model (visually a card with an input) to the collection and then force focus on the input of created card. I'm not sure if it's the correct way, but I basically listen to the event fired when model is added to collection and trigger another event which facilitates focusing from the view of created model:

# ItemView
initialize: ->
    App.vent.on "focus:field", =>
        $("div.card:last").addClass("edit")
        @$el.find("input:first").focus()

When I listen to the update event, it works as expected: :last card (the new model) is selected and input is focused.

But when I listen to the add event, initialize function fires on the penultimate model, instead of the new model. The new model is still created, but the edit class and focus is forced on the one before.

Why is that happens?

I would use an update event for this purpose, but unfortunately for me model.destroy method also fires an update event, so it results in ruined UI, and if I pass model.destroy with silient:true bad things happen overall. Is there a workaround?

Relevant code:

# CompositeView
class List.Models extends App.Views.CompositeView
    template: "path/to/template"
    childViewContainer: "div.destination"
    childView: List.Model
    events: 
        "click #add-model": "addModel"

    initialize: ->
        @listenTo @collection, "update", ->
            App.vent.trigger "focus:field"

    addModel: (e) ->
        @$el.find("#add-model").prop "disabled", true
        model = App.request "new:model:entity"
        @collection.add(model)

# ItemView
class List.Model extends App.Views.ItemView
    template: "path/to/template"

    initialize: ->
        App.vent.on "focus:field", =>
            $("div.card:last").addClass("edit")
            @$el.find("input:first").focus()

Edit: Apparently the difference between add and update events is that the add event is fired immediately after @collection.add(model) is called, but before new model is inserted in the DOM, resulting in $("div.card:last") selector pointing to the penultimate view. I'm not sure however, maybe more experienced people can clarify whether this is true or not. I've come to this conclusion after adding timeout to the execution of the App.vent:

initialize: ->
    delay = (ms, func) -> setTimeout func, ms
    # Triggered via add event
    App.vent.on "focus:field", =>
        delay 100, =>
            $("div.card:last").addClass("edit")
            $("input:first").focus()
Community
  • 1
  • 1
curious_gudleif
  • 572
  • 1
  • 4
  • 19
  • _initialize function fires on the penultimate model.._ What is the **penultimate model**? Could you post all relevant code? – hindmost Oct 25 '15 at 20:46
  • @hindmost, please take a look on this [updated jsfiddle](https://jsfiddle.net/DTcHh/13639/), it illustrates what I mean by penultimate model. Thanks for the reply. – curious_gudleif Oct 25 '15 at 20:54
  • Still unclear. Furthermore I don't see any Backbone code there. – hindmost Oct 25 '15 at 21:00
  • @hindmost, I've update the question with more code. – curious_gudleif Oct 25 '15 at 21:11
  • @curious_gudleif *"but before new model is inserted in the DOM"* - Backbone doesn't insert anything into the DOM. You should be doing that yourself. So it's easy to set it as focused where you're creating the new Element corresponding to the new model. – T J Oct 26 '15 at 03:34

0 Answers0