jquery 尝试理解Javascript中的DRY原则

hrirmatl  于 2022-11-03  发布在  jQuery
关注(0)|答案(4)|浏览(451)

我目前正在努力提高我的重构技能,我有一个代码块,我已经写了两个非常相似的方法,我正在努力简化我臃肿的代码,任何建议都是受欢迎的。
正如您所看到的,这两种方法非常相似,唯一真实的的区别是POST所指向的URL。

authenticateA : function( e ) {
  var $this = $( e.target ).closest( '[data-fn]' )
  ,   text = $this.text()
  ,   that = this;

  $this.text( 'Authenticating...' ).addClass("auth-button-disable")

  $.ajax({
    type : 'POST',
    url : '/A_authentications/update/',
    data : { _method : 'PUT', sms_token : this.$el.find( '#sms-input' ).val() },
    complete: function( xhr ) {

      if ( xhr.status === 200 )
        that.relocate();
      else {
        $this.text( text ).removeClass("auth-button-disable");
        that.handleError( xhr.status );
      }
    },
    dataType : 'json'
  });
},

authenticateB : function( e ) {
  var $this = $( e.target ).closest( '[data-fn]' )
  ,   text = $this.text()
  ,   that = this;

  $this.text( 'Authenticating...' ).addClass("auth-button-disable")

  $.ajax({
    type : 'POST',
    url : '/B_authentications/',
    data : { otp : this.$el.find( '#B-input' ).val() },
    complete: function( xhr ) {
      if ( xhr.status === 200 )
        that.relocate();
      else {
        $this.text( text ).removeClass("auth-button-disable");
        that.handleError( xhr.status )
      }
    },
    dataType : 'json'
  });
}

我在一个事件块中调用这些方法作为click函数:

'click [data-fn="authenticate-A"]' : 'authenticateA',
'click [data-fn="authenticate-B"]' : 'authenticateB'

我认为这些方法可以被重构为一个或两个更精简的方法,我只是不知道从哪里开始,再次提前感谢。

wsewodh2

wsewodh21#

您可以使用一个函数来生成这些函数:

generateAuthFunction : function( authDetails) {
  return function (e) {
    var $this = $( e.target ).closest( '[data-fn]' )
    ,   text = $this.text()
    ,   that = this;

    $this.text( 'Authenticating...' ).addClass("auth-button-disable")

    $.ajax({
      type : 'POST',
      url : authDetails.url,
      data : authDetails.dataFunc(this),
      complete: function( xhr ) {

        if ( xhr.status === 200 )
          that.relocate();
        else {
          $this.text( text ).removeClass("auth-button-disable");
          that.handleError( xhr.status );
        }
      },
      dataType : 'json'
    });
  };
}

然后使用以下命令生成:

var authDetailsA = {
  url :  '/A_authentications/update/',
  dataFunc : function (this) {
    return { _method : 'PUT', sms_token : this.$el.find( '#sms-input' ).val() };
  }
};
var authDetailsB = {
  url :  '/B_authentications/',
  dataFunc : function (this) {
    return { otp : this.$el.find( '#B-input' ).val() };
};
authenticateA : generateAuthFunction(authDetailsA);
authenticateB : generateAuthFunction(authDetailsB);

你可以像以前那样称呼它:

'click [data-fn="authenticate-A"]' : 'authenticateA',
'click [data-fn="authenticate-B"]' : 'authenticateB'

我认为这甚至可能会引入不必要的复杂性,但它更枯燥。

pn9klfpd

pn9klfpd2#

1.将请求抽象化。将应用逻辑混合到视图中只会使画面变得混乱。让我们创建一个Authentication模块:

var Authentication = (function(Backbone, _) {
    function whoGoesThere(opts) {
        opts = _.extend({}, opts, {
            type : 'POST',
            dataType: 'json'
        });

        return Backbone.$.ajax(opts);
    }

    return {
        A: function(data) {
            data = _.extend({}, data, {
                 _method : 'PUT'
            });
            return whoGoesThere({
                url : '/A_authentications/update/',
                data: data            
            });
        },
        B: function(data) {
            return whoGoesThere({
                url : '/B_authentications/',
                data: data            
            });
        }
    };
})(Backbone, _);

1.将视图配置为使用函数(而不是函数名)处理事件,将值传递给前一个模块上的相应方法,然后将返回的承诺委托给公共处理程序:

events: {
    'click [data-fn="authenticate-A"]': function(e) {
        var promise = Authentication.A({
            sms_token : this.$el.find( '#sms-input' ).val()
        });
        this.onAuthentication(e, promise);
    },
    'click [data-fn="authenticate-B"]': function(e) {
        var promise = Authentication.B({
            otp : this.$el.find( '#B-input' ).val()
        });
        this.onAuthentication(e, promise);
    }
}

1.处理promise(这里是 AJAX 对象,但可以是任何对象)

onAuthentication: function(e, promise) {
    var $this = $(e.target).closest('[data-fn]')
    ,   text = $this.text()
    ,   that = this;

    $this.text( 'Authenticating...' ).addClass("auth-button-disable");

    promise.done(function() {
        that.relocate();
    });
    promise.fail(function(xhr) {
        that.handleError(xhr.status);
    });
    promise.always(function() {
        $this.text(text).removeClass("auth-button-disable");        
    });
}

和演示http://jsfiddle.net/s3ydy3u6/1/

zmeyuzjn

zmeyuzjn3#

您可以只检查authenticate函数中的data-fn属性。

authenticate: function (e) {        
        var $this = $(e.target).closest('[data-fn]'),
            text = $this.text(),
            that = this;
        $this.text('Authenticating...').addClass("auth-button-disable");
        var fn = $this.data("fn");

        switch (fn) {
            case "authenticate-A":
                data = {
                    _method: 'PUT',
                    sms_token: this.$el.find('#sms-input').val()
                };
                url = '/A_authentications/update/';
                break;
            case "authenticate-B":
                data = {
                    otp: this.$el.find('#B-input').val()
                };
                url = '/B_authentications/update/';
                break;

        }

        $.ajax({
            type: 'POST',
            url: url,
            data: data,
            complete: function (xhr) {

                if (xhr.status === 200) that.relocate();
                else {
                    $this.text(text).removeClass("auth-button-disable");
                    that.handleError(xhr.status);
                }
            },
            dataType: 'json'
        });

    }
k2fxgqgv

k2fxgqgv4#

Try(未测试的程式码):

authenticate: function(t, e) { // t = 'A' || 'B'
  var $this = $( e.target ).closest( '[data-fn]' )
  ,   text = $this.text()
  ,   that = this
  ,   url
  ,   data;

  $this.text( 'Authenticating...' ).addClass("auth-button-disable")

  // conditionally set up your variables
  if(t == 'A') {
      data = { _method : 'PUT', sms_token : this.$el.find( '#sms-input' ).val() }; 
      url = '/A_authentications/update/';
  } else if(t == 'B') {
      url = '/B_authentications/';
      data = { otp : this.$el.find( '#B-input' ).val() };
  }

  $.ajax({
    type : 'POST',
    url : url, // use them
    data : data, // use them
    complete: function( xhr ) {

      if ( xhr.status === 200 )
        that.relocate();
      else {
        $this.text( text ).removeClass("auth-button-disable");
        that.handleError( xhr.status );
      }
    },
    dataType : 'json'
  });
},

相关问题