结合事件的看法 - 射击不均匀的次数 [英] Binding events to views - Firing uneven number of times

查看:138
本文介绍了结合事件的看法 - 射击不均匀的次数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的usermodel UserView UserCollection UserCollectionView 。有了这个,我试图绑定一个点击事件的 UserView (我在<$ C $这样做C> UserView )。所以,这是code我有:

  VAR根=的http://本地主机:5000 / API / V1';
VAR应用= {};//骨干示范
app.UserModel = Backbone.Model.extend({
    默认值:{
        // urlRoot:根+'/用户,
        名称:默认名称,
        电子邮件:30,
        用户名:default_username
    },    初始化:功能(){
        this.set({
            ID:this.get(用户名)
        });
        的console.log(用户模式\\''+ this.id +\\已被初始化。);
    },    //解析:功能(数据){
    //执行console.log('模式解析称为功能可按');
    //返回的数据;
    //}
});//骨干模型视图
app.UserView = Backbone.View.extend({
    // EL:'#用户列表,
    //标签名:'格',
    EL:'。用户-箱包装,    事件:{
        点击。用户数据':'userClicked
    },    userClicked:功能(EV){
        的console.log(用户选择);
        //执行console.log(ev.currentTarget);
    },    模板:_.template($('#连接用户模板)HTML()。)    初始化:功能(){
        this.render();
    },    渲染:功能(){
        $('#用户列表)追加(this.template(this.model.toJSON()));
        //这个$ el.append(this.template(this.model.toJSON()));
        的console.log('用户视图渲染');
    }
});//骨干集合
app.UserCollection = Backbone.Collection.extend({
    型号:app.UserModel,
    网址:根+'/用户,    初始化:功能(){
        // this.fetch();
    },    解析:功能(数据){
        //执行console.log(数据。数据);
        返回数据。数据;
    }
});//骨干集合视图
app.UserCollectionView = Backbone.View.extend({
    EL:'#用户列表,    模板:_.template($('#连接模板)HTML()。)    初始化:功能(){
        this.connections =新app.UserCollection();
        VAR自我=这一点;
        this.connections.fetch()。完成(功能(){
            self.render();
        });
    },    渲染:功能(){
        的console.log('用户集合视图渲染');
        。这$ el.html(this.template());
        //这个$ el.append(this.template(this.model.toJSON()));
        this.connections.each(功能(用户){
            的console.log('用户名:'+ user.get('身份证'));
            VAR userView =新app.UserView({
                模式:用户
            });
            // userView.model.fetch();
            // userView.render();
        });
    }
});
VAR connectionsView =新app.UserCollectionView();

的JSON数据实际上(在这种情况下,或UserModels)返回14的对象。问题是,如果我点击第一个用户视图,它被触发13次,而第二视图点击触发12次等等,不被点击时都引发了最后一个视图点击事件。

个人UserViews呈现各一次,但(这就是我认为至少)。有人可以请解释一下这里的问题是什么,究竟这里发生的事情?

P.S。 - 我知道了的CollectionView结合事件的解决办法的。

修改1

这是DOM结构:

 &LT;!DOCTYPE HTML&GT;
&LT; HTML和GT;
  &LT; HEAD&GT;
    &LT;标题&GT;嘿&LT; /标题&GT;
    &LT;链接rel =stylesheet属性HREF =../静态/ CSS / normalize.css&GT;
    &LT;链接rel =stylesheet属性HREF =../静态/ CSS / index.css&GT;
    &LT;脚本的src =/静态/ JS / jQuery的-2.2.0.js&GT;&LT; / SCRIPT&GT;
    &LT;脚本的src =/静态/ JS /下划线-1.8.3.js&GT;&LT; / SCRIPT&GT;
    &LT;脚本的src =/静态/ JS /骨干网1.2.3.js&GT;&LT; / SCRIPT&GT;
  &LT; /头&GT;  &LT;身体GT;
    &LT;标题ID =顶&GT;
      &LT; D​​IV ID =标志,包装&GT;
        &LT; IMG SRC =../静态/ IMG / logo.pngALT =标识ID =标志&GT;
      &LT; / DIV&GT;
      &LT; D​​IV ID =顶通&GT;
        &LT; D​​IV ID =顶级配置文件箱级=排名靠前&GT;
          &LT; D​​IV ID =顶级配置文件数据盒&GT;
            &LT; D​​IV ID =顶级配置文件数据名称&GT;凯文·艾萨克&LT; / DIV&GT;
            &LT; D​​IV ID =顶级配置文件的数据激情&GT;&作家LT; / DIV&GT;
          &LT; / DIV&GT;
          &LT; IMG ID =顶部轮廓图像SRC =../静态/ IMG / user1.jpgALT =&GT;
        &LT; / DIV&GT;
        &LT; D​​IV ID =通知图标级=排名靠前&GT;&LT; / DIV&GT;
        &LT; D​​IV ID =顶级消息图标级=排名靠前&GT;&LT; / DIV&GT;
        &LT; D​​IV ID =注销图标级=排名靠前&GT;&LT; / DIV&GT;
      &LT; / DIV&GT;
    &LT; /头&GT;
    &LT; D​​IV ID =中间&GT;
      &LT; NAV ID =边导航&GT;
        &LT; D​​IV ID =边导航顶&GT;
          &LT; D​​IV CLASS =边导航链接ID =边导航回家链接&GT;
            &LT; D​​IV CLASS =边导航链接-IMG&GT;&LT; / DIV&GT;
            &LT; D​​IV CLASS =边导航链接标题&GT;家庭和LT; / DIV&GT;
          &LT; / DIV&GT;
          &LT; D​​IV CLASS =边导航链接ID =边导航瞩目链接&GT;
            &LT; D​​IV CLASS =边导航链接-IMG&GT;&LT; / DIV&GT;
            &LT; D​​IV CLASS =边导航链接标题&GT;简介&LT; / DIV&GT;
          &LT; / DIV&GT;
          &LT; D​​IV CLASS =边导航链接ID =边导航的消息链接&GT;
            &LT; D​​IV CLASS =边导航链接-IMG&GT;&LT; / DIV&GT;
            &LT; D​​IV CLASS =边导航链接标题&gt;消息&LT; / DIV&GT;
          &LT; / DIV&GT;
          &LT; D​​IV CLASS =边导航链接ID =边导航账户链接&GT;
            &LT; D​​IV CLASS =边导航链接-IMG&GT;&LT; / DIV&GT;
            &LT; D​​IV CLASS =边导航链接标题&gt;帐户&LT; / DIV&GT;
          &LT; / DIV&GT;
        &LT; / DIV&GT;
      &LT; / NAV&GT;
      &LT; D​​IV ID =主要内容&GT;
        &LT;! - 网页HTML特定的开始 - &GT;        &LT; D​​IV ID =内容标题&GT;
          &LT; D​​IV CLASS =内容字幕ID =连接&GT;连接&LT; / DIV&GT;
          &LT; D​​IV CLASS =内容字幕ID =追随者&GT;关注&LT; / DIV&GT;
          &LT; D​​IV CLASS =内容字幕ID =以下&GT;追随中&LT; / DIV&GT;
        &LT; / DIV&GT;        &LT; D​​IV ID =内容主体&GT;
          &LT; D​​IV ID =用户箱&GT;
            &LT; D​​IV ID =用户列表&GT;无连接&LT; / DIV&GT;
              &LT;! - 主干模板开始。 - &GT;
              &LT;脚本类型=文/模板ID =连接模板&GT;&LT; / SCRIPT&GT;
              &LT;脚本类型=文/模板ID =连接用户模板&GT;
                &LT; D​​IV CLASS =用户箱包装&GT;
                  &LT; D​​IV CLASS =用户箱&GT;
                    &LT; D​​IV CLASS =用户PIC-包装&GT;
                      &所述; IMG SRC =/静态/ IMG / user1.jpgALT =&GT;
                    &LT; / DIV&GT;
                    &LT; D​​IV CLASS =用户数据ID =BOOX&GT;
                      &LT; D​​IV CLASS =用户名&GT;&LT;%=名称%GT;&LT; / DIV&GT;
                      &LT; D​​IV CLASS =用户的激情&GT;&LT;%=用户名%GT;&LT; / DIV&GT;
                      &LT; D​​IV CLASS =用户城市&GT;&LT;%=电子邮件%GT;&LT; / DIV&GT;
                    &LT; / DIV&GT;
                  &LT; / DIV&GT;
                &LT; / DIV&GT;
              &LT; / SCRIPT&GT;
              &LT;! - 主干模板完 - &GT;
            &LT; D​​IV ID =用户侧箱&GT;
              &LT; D​​IV ID =用户框搜索&GT;
                &LT;输入ID =用户搜索TYPE =文本名称=&GT;
              &LT; / DIV&GT;
              &LT; D​​IV ID =用户的元数据&GT;
                &LT; D​​IV ID =元数据用户机顶盒&GT;
                  &LT; D​​IV ID =元数据用户形象包装&GT;
                    &所述; IMG SRC =/静态/ IMG / user1.jpgALT =&GT;
                  &LT; / DIV&GT;
                  &LT; D​​IV ID =元数据的用户名框&GT;
                    &LT; D​​IV ID =元数据名称&GT;名称的债券&LT; / DIV&GT;
                    &LT; D​​IV ID =元数据激情&GT;刺客&LT; / DIV&GT;
                  &LT; / DIV&GT;
                &LT; / DIV&GT;
                &LT; D​​IV ID =元数据用户底盒&GT;
                  &LT; D​​IV CLASS =元数据的用户属性&GT;
                    &LT;跨度类=元数据属性&gt;对于就读:LT; / SPAN&GT;
                    &LT;跨度类=元价值&GT; Karunya大学&LT; / SPAN&GT;
                  &LT; / DIV&GT;
                  &LT; D​​IV CLASS =元数据的用户属性&GT;
                    &LT;跨度类=元数据属性&GT;当地城市:其中; / SPAN&GT;
                    &LT;跨度类=元价值&GT;伦敦和LT; / SPAN&GT;
                  &LT; / DIV&GT;
                  &LT; D​​IV CLASS =元数据的用户属性&GT;
                    &LT;跨度类=元数据属性&GT;网址:&LT; / SPAN&GT;
                    &LT;跨度类=元价值&GT; www.007.com&LT; / SPAN&GT;
                  &LT; / DIV&GT;
                &LT; / DIV&GT;
              &LT; / DIV&GT;
            &LT; / DIV&GT;
          &LT; / DIV&GT;
        &LT; / DIV&GT;        &LT;! - 网页特定的HTML结束 - &GT;
      &LT; / DIV&GT;
      &LT;一边ID =主搁置&GT;
        除了一二therr
      &LT; /一旁&GT;
    &LT; / DIV&GT;    &LT; SCRIPT SRC =../静态/ JS / index.min.js&GT;&LT; / SCRIPT&GT;
  &LT; /身体GT;
&LT; / HTML&GT;


解决方案

有您的code许多问题。

主要的问题是,所有的userView的都指向了相同的选择,以及元件匹配这个选择。用户-箱包装是视图模板里面 - 所以当你创建一个新的userView,它会在所有现有userViews添加一个新的事件监听器。用户-箱包装 present,而不是自己。所以,你的第一个userView将有 N-1 事件注册到它的处理程序,而最后一个现在没有( N 正在总数userViews的)。视图元件不应该是模板的一部分,模板是应该被添加到视图元素

当您的观点将有自身的多个副本,不要定义选项,让骨干视图的每个实例创建一个新元素。您可以自定义该元素的属性。

另一个问题是,你是不是追加userView模板,您userView元素,但外面(别的东西 $('#用户列表'),所以点击该模板将不会触发事件处理程序(在你的情况,这就是为什么你最后userView不会触发它的事件。它被绑定到所有其他现有的意见,因为常见的选择是由提供埃尔

您应该尽量避免像 $全球选择器('#用户列表')从视图中。在这种情况下,你可以将userView追加到#用户列表从内部userCollectionView谁的El点#用户列表

您code应该是:

VAR根=的http://本地主机:5000 / API / V1';
VAR应用= {};//骨干示范
app.UserModel = Backbone.Model.extend({
  默认值:{
    // urlRoot:根+'/用户,
    名称:默认名称,
    电子邮件:30,
    用户名:default_username
  },  初始化:功能(){
    this.set({
      ID:this.get(用户名)
    });
    的console.log(用户模式\\''+ this.id +\\已被初始化。);
  }
});//骨干模型视图
app.UserView = Backbone.View.extend({
  产品类别:用户箱包装,
  / * - ^ - 创建了这个类为每个用户*一个新的div /
  模板:_.template($('#连接用户模板)HTML()。)
  事件:{
    点击。用户数据':'userClicked
  },
  初始化:功能(){
    this.render();
  },
  渲染:功能(){
    这$ el.append(this.template(this.model.toJSON()));
    的console.log('用户视图渲染');
  },
  userClicked:功能(EV){
    的console.log(用户选择);
    //执行console.log(ev.currentTarget);
  }
});//骨干集合
app.UserCollection = Backbone.Collection.extend({
  型号:app.UserModel,
  网址:根+'/用户,
  初始化:功能(){
    // this.fetch();
  },
  解析:功能(数据){
    //执行console.log(数据。数据);
    返回数据。数据;
  }
});//骨干集合视图
app.UserCollectionView = Backbone.View.extend({
  EL:'#用户列表,
  模板:_.template($('#连接模板)HTML()。)
  初始化:功能(){
    this.connections =新app.UserCollection();
    VAR自我=这一点;
    this.connections.fetch()。完成(功能(){
      self.render();
    });
  },
  渲染:功能(){
    。这$ el.html(this.template());
    的console.log('用户集合视图渲染');
    this.connections.each(功能(用户){
      的console.log('用户名:'+ user.get('身份证'));
      VAR userView =新app.UserView({
        模式:用户
      });
      这$ el.append(userView.el); / *追加子视图这里* /
    },这个);
  }
});
VAR connectionsView =新app.UserCollectionView();

I have UserModel: UserView and UserCollection: UserCollectionView. With this, I am trying to bind a click event to the UserView (I am doing this in UserView). So, this is the code I have:

var root = 'http://localhost:5000/api/v1';
var app = {};

// Backbone Model
app.UserModel = Backbone.Model.extend({
    defaults: {
        // urlRoot: root + '/users',
        name: 'Default Name',
        email: '30',
        username: 'default_username'
    },

    initialize: function() {
        this.set({
            id: this.get('username')
        });
        console.log('User model \'' + this.id + '\' has been initialized.');
    },

    // parse: function(data) {
    //     console.log('Model parse funciton called');
    //     return data;
    // }
});

// Backbone Model View
app.UserView = Backbone.View.extend({
    // el: '#users-list',
    // tagName: 'div',
    el: '.user-box-wrapper',

    events: {
        'click .user-data': 'userClicked'
    },

    userClicked: function(ev) {
        console.log("User selected");
        // console.log(ev.currentTarget);
    },

    template: _.template($('#connections-user-template').html()),

    initialize: function() {
        this.render();
    },

    render: function() {
        $('#users-list').append(this.template(this.model.toJSON()));
        // this.$el.append( this.template( this.model.toJSON()));
        console.log('User view is rendered');
    }
});

// Backbone Collection
app.UserCollection = Backbone.Collection.extend({
    model: app.UserModel,
    url: root + '/users',

    initialize: function() {
        // this.fetch();
    },

    parse: function(data) {
        // console.log(data.data);
        return data.data;
    }
});

// Backbone Collection View
app.UserCollectionView = Backbone.View.extend({
    el: '#users-list',

    template: _.template($('#connections-template').html()),

    initialize: function() {
        this.connections = new app.UserCollection();
        var self = this;
        this.connections.fetch().done(function() {
            self.render();
        });
    },

    render: function() {
        console.log('User collection view is rendered');
        this.$el.html(this.template());
        // this.$el.append( this.template( this.model.toJSON()));
        this.connections.each(function(user) {
            console.log('User : ' + user.get('id'));
            var userView = new app.UserView({
                model: user
            });
            // userView.model.fetch();
            // userView.render();
        });
    }
});
var connectionsView = new app.UserCollectionView();

The JSON data actually returns 14 objects (or UserModels in this case). The problem is, if I click the first user view, it is triggered 13 times, and the second view click is triggered 12 times and so on, the last view click event not being triggered at all when clicked.

The individual UserViews are rendered once each, however (that's what I think at least). Can someone please explain what the problem here is and what exactly is happening here?

P.S. - I am aware of the workaround of binding the events in the CollectionView.

Edit 1

This is the DOM structure:

<!doctype html>
<html>
  <head>
    <title>Hey there</title>
    <link rel="stylesheet" href="../static/css/normalize.css">
    <link rel="stylesheet" href="../static/css/index.css">
    <script src="/static/js/jquery-2.2.0.js"></script>
    <script src="/static/js/underscore-1.8.3.js"></script>
    <script src="/static/js/backbone-1.2.3.js"></script>
  </head>

  <body>
    <header id="top">
      <div id="logo-wrapper">
        <img src="../static/img/logo.png" alt="Logo" id="logo">
      </div>
      <div id="top-links">
        <div id="top-profile-box" class="toplink">
          <div id="top-profile-data-box">
            <div id="top-profile-data-name">Kevin Isaac</div>
            <div id="top-profile-data-passion">Writer</div>
          </div>
          <img id="top-profile-image" src="../static/img/user1.jpg" alt="">
        </div>
        <div id="notification-icon" class="toplink"></div>
        <div id="top-message-icon" class="toplink"></div>
        <div id="logout-icon" class="toplink"></div>
      </div>
    </header>
    <div id="middle">
      <nav id="side-nav">
        <div id="side-nav-top">
          <div class="side-nav-link" id="side-nav-home-link">
            <div class="side-nav-link-img"></div>
            <div class="side-nav-link-title">Home</div>
          </div>
          <div class="side-nav-link" id="side-nav-profile-link">
            <div class="side-nav-link-img"></div>
            <div class="side-nav-link-title">Profile</div>
          </div>
          <div class="side-nav-link" id="side-nav-messages-link">
            <div class="side-nav-link-img"></div>
            <div class="side-nav-link-title">Message</div>
          </div>
          <div class="side-nav-link" id="side-nav-account-link">
            <div class="side-nav-link-img"></div>
            <div class="side-nav-link-title">Account</div>
          </div>
        </div>
      </nav>
      <div id="main-content">
        <!-- Start of page specific HTML -->

        <div id="content-title">
          <div class="content-subtitle" id="connections">Connections</div>
          <div class="content-subtitle" id="followers">Followers</div>
          <div class="content-subtitle" id="followings">Followings</div>
        </div>

        <div id="content-body">
          <div id="users-box">
            <div id="users-list">No connection</div>
              <!-- Backbone Template Starts --> 
              <script type="text/template" id="connections-template"></script>
              <script type="text/template" id="connections-user-template">
                <div class="user-box-wrapper">
                  <div class="user-box">
                    <div class="user-pic-wrapper">
                      <img src="/static/img/user1.jpg" alt="">
                    </div>
                    <div class="user-data" id="boox">
                      <div class="user-name"><%= name %></div>
                      <div class="user-passion"><%= username %></div>
                      <div class="user-city"><%= email %></div>
                    </div>
                  </div>
                </div>
              </script>
              <!-- Backbone Template Ends --> 


            <div id="users-side-box">
              <div id="users-box-search">
                <input id="user-search" type="text" name="">
              </div>
              <div id="user-metadata">
                <div id="metadata-user-top-box">
                  <div id="metadata-user-image-wrapper">
                    <img src="/static/img/user1.jpg" alt="">
                  </div>
                  <div id="metadata-user-name-box">
                    <div id="metadata-name">Name's Bond</div>
                    <div id="metadata-passion">Assassin</div>
                  </div>
                </div>
                <div id="metadata-user-bottom-box">
                  <div class="metadata-user-attribute">
                    <span class="metadata-property">Studied at: </span>
                    <span class="metadata-value">Karunya University </span>
                  </div>
                  <div class="metadata-user-attribute">
                    <span class="metadata-property">Native City: </span>
                    <span class="metadata-value">London</span>
                  </div>
                  <div class="metadata-user-attribute">
                    <span class="metadata-property">Website: </span>
                    <span class="metadata-value">www.007.com</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- End of page specific HTML -->
      </div>
      <aside id="main-aside">
        Aside one two therr
      </aside>
    </div>

    <script src="../static/js/index.min.js"></script>
  </body>
</html>

解决方案

There are many issues with your code.

Main problem is that, all your userView's are pointing to the same selector, and the element matching this selector .user-box-wrapper is inside the view template - So whenever you create a new userView, it'll add a new event listener to .user-box-wrapper present in all existing userViews, but not to itself. So your first userView will have n-1 events handlers registered to it while last one has none (n being total number of userViews). View element is not supposed to be part of template, template is supposed to be added to the view element.

When your view will have multiple copies of itself, don't define el option, let backbone create a new element for each instance of the view. You can customize the properties of this element.

Another issue is that you are not appending the userView template to your userView element, but something else outside it ($('#users-list'). So clicking the template won't trigger the event handler (in your case this is why you're last userView doesn't fire it's event. It was bound to all other existing views because common selector was provided by el)

You should try to avoid global selectors like $('#users-list') from within a view. In this case you can append the userView to #users-list from within userCollectionView who's el points to #users-list.

Your code should be:

var root = 'http://localhost:5000/api/v1';
var app = {};

// Backbone Model
app.UserModel = Backbone.Model.extend({
  defaults: {
    // urlRoot: root + '/users',
    name: 'Default Name',
    email: '30',
    username: 'default_username'
  },

  initialize: function() {
    this.set({
      id: this.get('username')
    });
    console.log('User model \'' + this.id + '\' has been initialized.');
  }
});

// Backbone Model View
app.UserView = Backbone.View.extend({
  className: 'user-box-wrapper',
  /*--^-- creates a new div with this class for each user*/
  template: _.template($('#connections-user-template').html()),
  events: {
    'click .user-data': 'userClicked'
  },
  initialize: function() {
    this.render();
  },
  render: function() {
    this.$el.append( this.template( this.model.toJSON()));
    console.log('User view is rendered');
  },
  userClicked: function(ev) {
    console.log("User selected");
    // console.log(ev.currentTarget);
  }
});

// Backbone Collection
app.UserCollection = Backbone.Collection.extend({
  model: app.UserModel,
  url: root + '/users',
  initialize: function() {
    // this.fetch();
  },
  parse: function(data) {
    // console.log(data.data);
    return data.data;
  }
});

// Backbone Collection View
app.UserCollectionView = Backbone.View.extend({
  el: '#users-list',
  template: _.template($('#connections-template').html()),
  initialize: function() {
    this.connections = new app.UserCollection();
    var self = this;
    this.connections.fetch().done(function() {
      self.render();
    });
  },
  render: function() {
    this.$el.html(this.template());
    console.log('User collection view is rendered');
    this.connections.each(function(user) {
      console.log('User : ' + user.get('id'));
      var userView = new app.UserView({
        model: user
      });
      this.$el.append(userView.el); /*append child view here*/
    },this);
  }
});
var connectionsView = new app.UserCollectionView();

这篇关于结合事件的看法 - 射击不均匀的次数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆