0

EDIT1: I have tried many different strategies for deleting the element including this.model.destroy(), this.collection.remove(this.model), etc. I have also bound the events using the events: syntax and using a direct binding strategy in both initialize and render.

If I change the code to use this.collection.add instead of remove it adds an additional X notes where X is the number of notes currently in the collection.

I am writing a basic list app (to be fleshed out eventually) and I want each element in the list to have a button that will delete it from the list.
I am using

  • require.js
  • backbone
  • lo-dash
  • jquery

My code snippets below show my view code for the Notes View, Note View and some supporting into including the templates being used to render each.

At the moment, the code is not functioning as desired because clicking ANY Note's "hide" button causes all elements in the collection to be removed one at a time. I know that is what is happening because I can insert alerts at the end of the "deletenote" method which allows me to view the deletion piece-wise.

I also know that the parent render method is not the cause of the problem because I can turn off the event callback to re-render the parent NotesView and all Note views are still deleted.

<script type="text/template" id="noteslist-template">
    <ul id="noteslist" style="list-style: none;">
    </ul>
</script>

<script type="text/template" id="note-template">
<li>
    <button type="button" class="notesbutton" id="hidenote">hide</button>
    <div id="note"><%= text %></div>
</li>
</script>

NotesView.js

define
([  'jquery',
'underscore',
'backbone',
'notes/sample/sampletext',      //included to populate a collection for rendering *REMOVE ONCE DONE TESTING*
'notes/collections/Notes',      //included to create a new instance of the Notes collection during the initialize method of this view
'notes/models/Note',            //included to reference the model when creating NoteView instances for rendering
'notes/views/NoteView'      ],  //included to call render functions on each Note model in the collection
function($,_,Backbone,SampleText,Notes,Note,NoteView)
{
    var NotesView = Backbone.View.extend
    ({
        initialize: function() 
        {
            this.template = _.template($('#noteslist-template').html());
            _.bindAll(this,'render','rendernote');
            this.collection.bind('add',this.render);
            this.collection.bind('remove',this.render);
        },
        render: function() 
        {
            console.log('collection render');
            this.$el.html(this.template({}));       //change to this.notelist = THISLINE
            this.collection.each(this.rendernote);
            //add call to render notelist to DOM
            return this;
        },
        rendernote: function(note)      //add notelist variable
        {
            console.log('collection rendernote');
            var noteview = new NoteView(
                                {   model:note,
                                    collection:this.collection} );
            //add notelist  +=  LINEBELOW
            noteview.setElement(this.$('#noteslist'));
            noteview.render();
            //change noteview.render to NOT write to DOM
        }
    });
    return NotesView;
}
);

NoteView.js

define
(   [   'jquery',
    'underscore',
    'backbone',
    'notes/models/Note',    ],  //include the Note model to reference as the model for the collection
function($,_,Backbone,Note)
{
    var NoteView = Backbone.View.extend
    ({
        tagName: "li",
        className: "note",

        events:
        {
            'click #hidenote':'deletenote',

        },

        initialize: function()
        {
            _.bindAll(this,'render','remove','deletenote');
            //this.model.bind('change',this.render);
            this.template = _.template($('#note-template').html());
            this.model.bind('remove', this.remove);
        },
        render: function()
        {
            this.notetorender = this.template(this.model.toJSON());
            this.$el.append(this.notetorender);
            return this;
        },
        deletenote: function()
        {
            this.options.collection.remove(this.model);
        }
    });
    return NoteView;
}
);
4

2 回答 2

1

noteview.setElement(this.$('#noteslist')); causes event delegation. So eventhough you wrote 'click #hideNotes : deleteNode' inside NoteView, after the setElement call it works like that code is present inside NotesListView.

So when you click hide button of single li and expect only that li to be removed from ul however the click event is received by all li's hide button.That's why all items in collection are deleted .

JsFiddle here i do the same thing without using setElement

于 2012-10-29T19:20:00.140 回答
0
var NoteView = Backbone.View.extend({
    events: {'click #hidenote': 'deletenote'},
    initialize: function(){
        this.model.on('destroy', this.$el.remove)
    },
    deletenote: function(){
        this.model.destroy()
    }
})
于 2012-10-29T12:05:32.037 回答