【问题标题】:Backbone Event is firing on parent's View主干事件在父视图上触发
【发布时间】:2012-06-26 05:21:55
【问题描述】:

我是 Backbone.js 的新手,到目前为止我很喜欢它,我一直在使用 Require.js 来模块化整个项目。到目前为止一切顺利,但我确实在事件绑定方面遇到了一些问题。

基本上我想要做的是,当你第一次进入注册页面时,路由器将呈现 registerView。在注册视图中,您将看到一个链接,稍后我将添加更多按钮,一旦我得到这个工作。

当点击链接时,我会触发 showLogin 事件并调用 showLogin 函数,并将登录视图渲染到 div (#login-container) 中。由于某种原因,我不能使用$(this.el).html(template(data));。但是我通过使用 jquery 选择器将视图加载到正确的 div 中来解决它。有人可以向我解释为什么$(this.ellogin.js 中不起作用吗?

现在的主要问题是,当有人单击登录按钮时,我想触发另一个事件。我以为我可以在 loginView(Login.js) 中触发该事件,但该事件是在父视图 (Register.js) 中触发的。当我单击按钮时,javascript 控制台将打印:

Register.js Login Clicked

由于我对这个新框架相当陌生,肯定有一些我忘记添加的东西,或者我做错了事。我希望有更多经验的用户指出我的错误。有什么想法吗?

index.html

<div class="container">
  <div id="content">
  </div>
</div> <!-- /container -->

login.html

<div id="signin">  
  <form action="">
    <fieldset>
      <legend>Login</legend>
      <input id="login" type="button" value="Login">
    </fieldset>
  </form>
</div>

register.html

<ul>
  <li id="login-li"><a id="showlogin">I already have an account</a></li>
</ul>
<div id="login-container">
</div>

router.js

define([
  'jquery',
  'underscore', 
  'backbone',
  'views/register'

  ], function($, _, Backbone, registerView){
  var AppRouter = Backbone.Router.extend({

    routes: {
      "register": "registerView"
    },

    registerView: function() {
      registerView.render();
    }
  });

  return AppRouter;
});

login.js

define([
  'jquery',
  'underscore',
  'backbone',
  'text!templates/login.html'
], function($, _, Backbone, loginTemplate){

  var loginView = Backbone.View.extend({
    el: $("#login-container"),
    initialize: function() {
      _.bindAll(this, 'render'); // fixes loss of context for 'this' within methods
    },

    events: {
      "click input#login":  "login"
    },

    render: function(){
      var data = {};
      var template = Handlebars.compile(loginTemplate);
      $("#login-container").html(template(data));

      #
      # Why the following code does not work like in register.js?
      # $(this.el).html(template(data));
      #

    }, 

    login: function() {
      console.log("Login.js Login Clicked");
    }

  });
  return new loginView;
});

register.js

define([
  'jquery',
  'underscore',
  'backbone',
  'views/login',
  'views/signup',
  'text!templates/register.html'
], function($, _, Backbone, loginView, signupView, registerTemplate){

  var registerView = Backbone.View.extend({
    el: $("#content"),

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

    events: {
      "click a#showlogin":  "showLogin",
      "click input#login": "login",
    },

    render: function(){
      var data = {};

      var template = Handlebars.compile(registerTemplate);
      $(this.el).html(template(data));
    },

    showLogin: function() {
      loginView.render();
    },

    login: function() {
      console.log("Register.js Login Clicked");
    }
  });
  return new registerView;
});

【问题讨论】:

    标签: events view backbone.js


    【解决方案1】:

    在 DOM 树中有一个 ID 为 #login-container 的 DOM 元素(仅当 registerView 被渲染时添加)之前初始化 loginView,所以事情自然有点混乱。

    纠正这种情况的方法不是像return new xView那样在各自的模块中返回每个视图的实例,而是像这样return xView那样返回“类”,然后在需要时像这样初始化它们

    showLogin: function() {
      (new loginView()).render();
    }
    

    【讨论】:

    • 我试过你的建议,但没有任何区别。
    • el: $("#login-container") 更改为el: "#login-container"。 el 变量不适用于 jQuery 对象,有一个单独的$el,但你不应该自己设置它。
    • 是的,最后。非常感谢。
    猜你喜欢
    • 2012-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多