繁体   English   中英

jQuery重构-DRY

[英]jQuery Refactoring - DRY

我的主要功能内部有这两个功能。 正如您将看到的,两者之间的唯一区别在于中间如何附加/编辑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');
});

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

你是在自问自答! “正如您将看到的,两者之间的唯一区别在于它们附加/编辑html的方式在中间。” 最初的一次天真的,机械的重构尝试可能看起来像这样,只是将所有通用代码提取到共享函数中:

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');

});

当只有两种情况时,它并不能真正赢得您那么多。 但是,如果有两个以上的人员进行这种重构,就会开始获得回报。

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

通常,我喜欢创建某种控制器类,该类可以为应用程序中的每个页面执行所有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);
    };
}

只谈论使代码DRY(相对于通常对其进行适当的架构设计),我可能会将代码重写为:

 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); }); 

基本上,您:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM