2015-06-13 8 views
1

У меня есть две функции внутри моей основной функции. Как вы увидите, единственное различие между ними - посередине с тем, как они добавляют/редактируют html. Я думаю, было бы неплохо придумать две новые функции: ту, которая делает первую половину, а вторую - вторую половину. Я не уверен, что это возможно с помощью jQuery или даже с JavaScript, поскольку я не знаю, как назвать эти новые функции внутри этих функций, если это имеет смысл. Любая помощь/руководство будет замечательным!jQuery Рефакторинг - DRY

Вот первые один

$('#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'); 
}); 

И, конечно, если у кого есть какие-либо предложения по любым другим аспектам моего кода, я являюсь для критики!

+2

Уточняете, что вы подразумеваете под второй половиной? Также при выполнении одного и того же действия на нескольких селекторах вы можете сохранять ресурсы и вводить их, выбирая их все сразу: '$ ('. Title-warn, .tags-warn, .notes-warn'). Hide();' just a маленький трюк, который вы можете реализовать, если вы чувствуете приключения. ;) – CalebB

+0

Я просто имел в виду часть после того, где я добавлял/редактировал html. Я обязательно включу трюк, хотя, спасибо! –

ответ

2

Вы ответили на свой вопрос! «Как вы увидите, единственная разница между ними - посередине с тем, как они добавляют/редактируют 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'); 

}); 

Это не реально выиграть, что много, когда есть только два сценария , Но с более чем двумя делами такой рефакторинг начинает пожинать плоды.

Эта первая попытка может быть усовершенствована (много). Возможно, хорошие люди будут публиковать. Но это была бы хорошая первая попытка.

+0

Согласен. Если это не так, эта первая попытка - это минимальный минимум, который вы должны серьезно рассмотреть. –

0

Как правило, мне нравится создавать своего рода класс контроллера, который делает все пользовательские интерфейсы для каждой страницы в моем приложении. Это упрощает тестирование, потому что вы можете очень легко использовать свои целевые методы.

Мне также нравится скрывать свои селекторы за легко читаемыми переменными, поэтому, если бы я прочитал этот файл через несколько недель/месяцев, я быстро смогу ускорить, прочитав, что такое высокоуровневая логика намереваясь сделать. (FYI в моем ответе ниже, я этого не делал). На самом деле я не знаю, что должен представлять файл editTitle. Но вот несколько примеров того, как я бы переименовал его как: TaskTitle, BlogTitle и т. Д.)

Это все рекомендации на самом деле, но мне жаль, что я никогда не писал такой код. Я бы рекомендовал вам вынимают некоторое время и просто читать о яваскрипта шаблонов проектирования, программирования идиомы и т.д.

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

Говоря только о том, чтобы код DRY (по сравнению с примерно architecturing это правильно вообще), я, наверное, переписать код, как:

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. Не повторяйте var на каждое объявление переменной. Используйте запятые, чтобы разделить декларации под тем же var. Хотя это не большая проблема с DRY, но это делает код короче и приятнее.
  2. Идентифицируйте повторяющиеся/похожие материалы и сквойте их в:
    • Петли над массивами, которые содержат различия. В вашем случае это будет массив IDs ['title', 'tags', 'notes']; OR
    • Методы принятия различий в качестве аргументов. В вашем случае оба обработчика «edit» и «save» довольно похожи, что должно быть первым сигналом для вас, чтобы обернуть их в именованный метод (handler в моем примере).
Смежные вопросы