jQuery重构 - 干

时间:2015-06-13 03:23:21

标签: javascript jquery refactoring dry

我在main函数中有这两个函数。正如你所看到的那样,两者之间的唯一区别在于他们如何追加/编辑html。我认为提出两个新功能会很好,一个是上半部分,另一个是下半部分。我不确定这是否可以使用jQuery,或者甚至用JavaScript来解决这个问题,因为我不知道如何在这些函数中调用这些新函数,如果这有意义的话。任何帮助/指导都会很棒!

这是第一个

$('#save').click(function(){
var title = $('#title').val();
var tags = $('#tags').val();
var notes = $('#notes').val();
var myDate = new Date();
if (title.length < 1) {
  $('.title-warn').show();
}
if (tags.length < 1) {
  $('.tags-warn').show();
}
if (notes.length < 1) {
  $('.notes-warn').show();
}
if (title.length >= 1 && tags.length >= 1 && notes.length >= 1) {
  $allNotes.prepend('<li class="note"><div><h1>' + title + '</h1><div class="date">      <h2>'+ myDate.toDateString() +'</h2><span class="btn btn-edit">Edit</span></div><h3>' + tags + '</h3><p>' + notes + '</p></div></li>');
  $allNotes.show();
  $newNote.hide();
  $('.title-warn').hide();
  $('.tags-warn').hide();
  $('.notes-warn').hide();
}
$('#title').val('');
$('#tags').val('');
$('#notes').val('');
$('#search').prop('disabled', false);
$('#search').attr("placeholder", "Search by title, tags, date, or even words/sentences in notes");
$('.btn-search').prop('disabled', false);
});

现在是第二个

$('#edit').click(function(){
var title = $('#edit-title').val();
var tags = $('#edit-tags').val();
var notes = $('#edit-notes').val();
var myDate = new Date();
if (title.length < 1) {
  $('.title-warn').show();
}
if (tags.length < 1) {
  $('.tags-warn').show();
}
if (notes.length < 1) {
  $('.notes-warn').show();
}
if (title.length >= 1 && tags.length >= 1 && notes.length >= 1) {
  $('.edited-note').html('<div><h1>' + title + '</h1><div class="date">      <h2>'+ myDate.toDateString() +'</h2><span class="btn btn-edit">Edit</span></div><h3>' + tags + '</h3><p>' + notes + '</p></div>');
  $('.allnotes').show();
  $('.edit-note').hide();
  $('.title-warn').hide();
  $('.tags-warn').hide();
  $('.notes-warn').hide();
}
$('#title').val('');
$('#tags').val('');
$('#notes').val('');
$('#search').prop('disabled', false);
$('#search').attr("placeholder", "Search by title, tags, date, or even words/sentences in notes");
$('.btn-search').prop('disabled', false);
$('.edited-note').removeClass('edited-note');
});

当然,如果有人对我的代码的任何其他方面有任何建议,我都会受到批评!

3 个答案:

答案 0 :(得分:2)

你回答了自己的问题! &#34;正如你所看到的那样,两者之间的唯一区别在于他们如何追加/编辑html。&#34;重构的初始非常天真和机械的尝试可能看起来像这样,只是将所有公共代码拉出到共享函数中:

function preHandler(title, tags, notes) {
    if (title.length < 1) {
        $('.title-warn').show();
    }
    if (tags.length < 1) {
        $('.tags-warn').show();
    }
    if (notes.length < 1) {
        $('.notes-warn').show();
    }

    return title.length >= 1 && tags.length >= 1 && notes.length >= 1;

}


function commonPost () {

    $('#title').val('');
    $('#tags').val('');
    $('#notes').val('');
    $('#search').prop('disabled', false);
    $('#search').attr("placeholder", "Search by title, tags, date, or even words/sentences in notes");
    $('.btn-search').prop('disabled', false);


}



$('#save').click(function(){
    var title = $('#title').val();
    var tags = $('#tags').val();
    var notes = $('#notes').val();
    var myDate = new Date();
    if  (preHandler(title, tags, notes)) {

        $allNotes.prepend('<li class="note"><div><h1>' + title + '</h1><div class="date">      <h2>'+ myDate.toDateString() +'</h2><span class="btn btn-edit">Edit</span></div><h3>' + tags + '</h3><p>' + notes + '</p></div></li>');
        $allNotes.show();
        $newNote.hide();
        $('.title-warn').hide();
        $('.tags-warn').hide();
        $('.notes-warn').hide();

    }
    commonPost();

});


$('#edit').click(function() {
    var title = $('#edit-title').val();
    var tags = $('#edit-tags').val();
    var notes = $('#edit-notes').val();
    var myDate = new Date();

    if  (preHandler(title, tags, notes)) {

        $('.edited-note').html('<div><h1>' + title + '</h1><div class="date">      <h2>'+ myDate.toDateString() +'</h2><span class="btn btn-edit">Edit</span></div><h3>' + tags + '</h3><p>' + notes + '</p></div>');
        $('.allnotes').show();
        $('.edit-note').hide();
        $('.title-warn').hide();
        $('.tags-warn').hide();
        $('.notes-warn').hide();

    }

    commonPost();
    $('.edited-note').removeClass('edited-note');

});

当只有两种情况时,它并没有真正赢得你那么多。但有两个以上做这种重构开始获得回报。

第一次尝试可以改进(很多)。也许好人会发帖。但这将是一次良好的首次尝试。

答案 1 :(得分:0)

通常我喜欢创建某种控制器类,它可以为我的应用程序中的每个页面执行所有UI工作。这使得测试变得更加容易,因为您可以以非常简单的方式调用目标方法。

我也喜欢将我的选择器隐藏在容易阅读的变量之后,所以如果我从现在开始几周/几个月内读取这个文件,我可以通过阅读高级逻辑意图来快速提高自己的速度去做。 (仅在我下面的答案中我没有做到这一点。我实际上并不知道editTitle应该代表什么。但是这里有几个例子我将如何重命名为:TaskTitle,BlogTitle等)

这些都是指南,但我希望我总是这样写我的代码。我建议你花点时间阅读一下javascript设计模式,编程习语等等。

var myApp = new app();

$(function () {
    myApp.init();
});

var app = function () {
    var editTitle = "#edit-title";
    var editTitleWarning = ".title-warn";

    var editTags = "#edit-tags";
    var editTagsWarning = ".tags-warn";

    var editNotes = "#edit-notes";
    var editNotesWarning = ".notes-warn";

    var saveButton = "#save";
    var editButton = "#edit";

    var updateUI = function (args) {
        var isSave = args.data.isSave;
        var title = $(editTitle).val();
        var tags = $(editTags).val();
        var notes = $(editNotes).val();
        var myDate = new Date();

        // (suggestion) add comment here 
        if (title.length < 1) {
            $(editTitleWarning).show();
        }

        // (suggestion) add comment here 
        if (tags.length < 1) {
            $(editTagsWarning).show();
        }

        // (suggestion) add comment here 
        if (notes.length < 1) {
            $(editNotesWarning).show();
        }

        if (isSave) {
            // add save append code here
        } else {
            // add edit html code here
        }

        // add remaining code here
    };

    this.init = function () {
        $("body")
            .on("click", saveButton, { isSave = true }, updateUI)
            .on("click", editButton, { isSave = false }, updateUI);
    };
}

答案 2 :(得分:0)

仅谈论使代码DRY(而不是正常构建它),我可能会将代码改写为:

&#13;
&#13;
var handler = function(prefix, htmlHandler, removeEditedNoteCls) {
    prefix = '#' + (prefix === false ? '' : (prefix + '-'));
    var list = ['title', 'tags', 'notes'],
      i = 0,
      h = {
        date: new Date
      },
      act = true;
    for (; i < list.length; i++) {
      h[list[i]] = $(prefix + list[i]).val();
      if (h[list[i]].length < 1) {
        $('.' + list[i] + '-warn').show();
        act = false;
      }
    }
    if (act) {
      htmlHandler.call(this, h);
      for (i = 0; i < list.length; i++) {
        $('.' + list[i] + '-warn').hide();
      }
    }
    for (i = 0; i < list.length; i++) {
      $('#' + list[i]).val('');
    }
    $('#search').prop('disabled', false);
    $('#search').attr("placeholder", "Search by title, tags, date, or even words/sentences in notes");
    $('.btn-search').prop('disabled', false);
    if (removeEditedNoteCls) {
      $('.edited-note').removeClass('edited-note');
    }
  },
  prepend = function(h) {
    $allNotes.prepend('<li class="note"><div><h1>' + h.title + '</h1><div class="date">      <h2>' + h.date.toDateString() + '</h2><span class="btn btn-edit">Edit</span></div><h3>' + h.tags + '</h3><p>' + h.notes + '</p></div></li>');
    $allNotes.show();
    $newNote.hide();
  },
  replace = function(h) {
    $('.edited-note').html('<div><h1>' + h.title + '</h1><div class="date">      <h2>' + h.date.toDateString() + '</h2><span class="btn btn-edit">Edit</span></div><h3>' + h.tags + '</h3><p>' + h.notes + '</p></div>');
    $('.allnotes').show();
    $('.edit-note').hide();
  };
$('#save').click(function() {
  handler('', prepend);
});
$('#edit').click(function() {
  handler('edit', replace, true);
});
&#13;
&#13;
&#13;

基本上,你:

  1. 不要在每个earch变量声明中重复var。使用逗号分隔同一var下的声明。尽管与DRY没什么关系,但它使代码更短更好。
  2. 识别重复/类似的东西并将其挤压成:
    • 仅对包含差异的数组进行循环。在您的情况下,它将是ID ['title', 'tags', 'notes']的数组; OR
    • 接受差异作为参数的方法。在你的情况下,&#34;编辑&#34;并且&#34;保存&#34;处理程序非常相似,这应该是第一个将它们包装到命名方法中的信号(在我的示例中为handler)。