繁体   English   中英

Backbone视图中的事件,可以在应用程序中多次添加

[英]Events in a Backbone view that can be added multiple times in the application

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

<!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将出现一个警报 - 一个对应于添加的每个项目。这不是我想要的方式。我希望仅针对已单击的Backbone View触发事件,以便我可以访问我点击了Backbone View的模型。

我如何才能实现这一功能?。如果我的问题不明确,请告诉我。谢谢。

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

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

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

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

这是因为您正在为每个项创建视图类的新实例,为每个实例分配相同的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方法执行添加项目,这样便于维护这样的项目视图对象数组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM