1

在解释我面临的问题之前,这是我正在使用的代码:

<!DOCTYPE HTML>
<html>
    <head>
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
        <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.1/underscore-min.js"></script>
        <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
        <script type="text/template" id="view_template">
            <li>
            <label class="lbl" style="width:100px;display:inline-block;"><%= name %></label>
            <button class="btn">Click</button>
            </li>
        </script>
        <script type="text/javascript">
            AppModel = Backbone.Model.extend({
                defaults : {
                    m_name : "Default name"
                },
                modify : function(value) {
                    this.set({
                        m_name : value
                    });
                }
            });

            $(document).ready(function() {
                $("#add").click(function() {
                    var appModel = new AppModel();
                    appModel.modify($("#txt").val());
                    new CustomView({
                        model : appModel
                    });
                    $("#txt").val("");
                });
                CustomView = Backbone.View.extend({
                    el : $(".list"),
                    events : {
                        "click .btn" : "showAlert"
                    },
                    initialize : function() {
                        this.render();
                    },
                    render : function() {
                        var variables = {
                            name : this.model.get("m_name")
                        };
                        var t = _.template($("#view_template").html(), variables);
                        $(this.el).append(t);
                    },
                    showAlert : function() {
                        alert(this.model.get("m_name"));
                    }
                });
            });

        </script>
    </head>
    <body>
        <input type="text" id="txt"/>
        <button id="add">
            Add
        </button>
        <ul class="list" style="list-style: none"></ul>
    </body>
</html>

演示在这里 - http://jsfiddle.net/jCekv/

您可以在文本字段中输入任何值并单击添加。文本将添加到一个主干视图列表中。您可以继续向列表中添加多个值。添加一些项目后,单击任何一个中的单击按钮列表中的项目。我想获取该视图的模型中的值。但是由于我添加的方式Events,事件处理程序被多次执行。例如:如果我添加 3 个项目并单击任何按钮在列表中,3 个警报将与添加的每个项目相对应。这不是我想要的方式。我希望仅针对已单击的主干视图触发事件,以便我可以访问我点击的主干视图的模型。

我怎样才能实现这个功能?如果我的问题不清楚,请告诉我。提前致谢。

4

2 回答 2

2

问题是你所有CustomViews的元素都设置为$(".list"). 因此,所有委托事件都被添加到同一个 DOM 元素、列表中,而不是单个列表项。

在此处查看可能的解决方案:http: //jsfiddle.net/mbuchetics/R8jPA/

我将其更改CustomView为使用tagNameofli而不是设置元素。模板没有附加到元素上,而是设置了它的内容。这样,每个都CustomView代表列表中的一个项目,而单击事件正是指该项目。我还从初始化中删除了渲染调用,而是在将视图附加到列表时呈现视图(在“添加单击”回调中)。 Render()返回this,因此您可以使用它view.render().el来获取列表项的 html。

您可以进一步改进您的应用程序以使用集合和集合的单独视图。然后,集合视图可以处理集合上的“添加”等事件,并相应地更新自身(以及各个项目视图)。

于 2012-05-07T13:04:59.133 回答
1

这是因为您正在为每个项目创建视图类的新实例,将相同的 DOM 元素(对应于整个列表,而不是单个项目)分配给每个实例,并注册相同的事件侦听器。因此,每次单击任何按钮时,都会为每个视图对象触发事件侦听器。

像这样的东西会起作用:

http://jsfiddle.net/jCekv/1/

$( document ).ready( function () {

  $( "#add" ).click( function () {

    var appModel = new AppModel();

    appModel.modify( $( "#txt" ).val() );

    var item = new Item_View( {

      model : appModel

    } );

    list.add_item( item );

    $( "#txt" ).val( "" );

  } );


  var List_View = Backbone.View.extend( {

    el : $( ".list" ),

    events : {

      "click .btn" : "showAlert"

    },

    initialize : function () {

      this.render();

    },

    add_item : function ( item ) {

      item.render();

      item.$el.data( 'view_object', item );

      this.$el.append( item.el );

    },

    showAlert : function ( event ) {

      alert(

        $( event.target )

          .closest( 'li' )

          .data( 'view_object' )

          .model.get( "m_name" )

      );

    }

  } );


  var Item_View = Backbone.View.extend( {

    tagName : 'li',

    render : function() {

      var variables = {

        name : this.model.get( "m_name" )

      };

      var t = _.template( $( "#view_template" ).html(), variables );

      this.$el.html( $( t ).html() );

      return this;

    }

  } );


  var list = new List_View;

} );
  • 我为列表和项目创建了单独的视图类。

  • 我使用 为每个项目存储对视图对象的引用jQuery.data,以便可以在事件侦听器 ( ) 中检索视图对象(以及通过它,模型对象showAlert)。或者,您可以在列表视图中维护项目的视图对象数组。我已经有了这个设置来通过add_item列表视图的方法执行添加项目,这样可以方便地维护这样一个项目视图对象数组。

于 2012-05-07T12:52:45.257 回答