1

ログインフォームとして機能するMarionette.jsビューがあります。次のコード サンプルは、既に修正済みのエラーを含む関連するコード部分を示しています。

MyApp.module("User", function(User, App, Backbone, Marionette, $, _) {

  User.LoginView = Marionette.ItemView.extend({

    className: "reveal-modal",
    template: "user/login",

    ui: {
      signInForm: "#signin-form"
    },

    events: {
      "submit #signin-form": "onSignInFormSubmit"
    },

    onRender: function() {
      var self = this;
      var $el = this.$el;

      // [...] Render schema

      _.defer(function(){
        $el.reveal({
          closeOnBackgroundClick: false,
          closed: function(){
            self.close(); // <-- This is incorrect. Do not close the ItemView directly!
          }
        });
      });
    },

    onSignInFormSubmit: function(event) {
      event.preventDefault();
      var errors = this.signInForm.validate();
      var data = this.signInForm.getValue();
      // [...] Notify that data has been submitted.    
    },

    hideForm: function() {
      this.$el.trigger("reveal:close");
    }

  });
});

実装の大きな間違いに気付きました。Revealのコールバック関数closedで、直接ItemViewを閉じることにしましたが、これはMarionette.js のドキュメントで読むことができるように間違っています。

View は、領域マネージャーによって自動的に呼び出される close メソッドを実装します。

バグ修正:代わりにregionclose()で呼び出す必要があります。このエラーを修正しました。


ここで、問題をカバーするテストを実際にどのように作成できるかを自問します。テストにはジャスミンを使用します。ItemViewを誤って閉じてフォームを再送信しようとした後、イベント ハンドラーonSignInFormSubmit呼び出されなくなったことに気付きました。

これは、残念ながらバグ修正でも失敗するテストの最初のドラフトです。

it("should call the submit handler for the sign-in form", function() {
  spyOn(userController.loginView, "onSignInFormSubmit");
  spyOn(userController.loginView.signInForm, "validate").andCallFake(function(params) {
    return null;
  });
  userController.loginView.hideForm();
  userController.loginView.ui.signInForm.trigger("submit");
  expect(userController.loginView.onSignInFormSubmit).toHaveBeenCalled();
});

次のようにイベントハンドラーが登録されているかどうかをテストすることもできます。

expect(userController.loginView.events["submit #signin-form"]).toEqual("onSignInFormSubmit");
4

0 に答える 0