0

私はBackbone.jsを初めて使用します。これまでのところ気に入っています。プロジェクト全体をモジュール化するために、Require.jsを使用しています。これまでのところ良好ですが、イベントバインディングでいくつかの問題が発生します。

基本的に私がやろうとしていることは、最初に登録ページに入ると、ルーターがregisterViewをレンダリングすることです。レジスタービュー内にリンクが表示されます。これが機能するようになったら、後でボタンを追加します。

リンクがクリックされると、showLoginイベントを起動してshowLogin関数を呼び出し、ログインビューをdiv(#login-container)にレンダリングします。$(this.el).html(template(data));なんらかの理由で使えません。しかし、jqueryセレクターを使用してビューを正しいdivにロードすることで回避できます。誰かが私になぜが$(this.el機能しないのか説明できますかlogin.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;
});
4

1 に答える 1

2

DOMツリーにidを持つDOM要素(registerViewがレンダリングされ#login-containerたときにのみ追加される)が存在する前にloginViewを初期化するので、当然、物事は少し混乱します。

この状況を修正するためにできることは、このようにそれぞれのモジュールで各ビューのインスタンスを返すのではなく、このreturn new xViewように「クラス」を返し、return xView必要に応じてこのように初期化することです。

showLogin: function() {
  (new loginView()).render();
}
于 2012-06-26T07:39:02.053 に答える