问题描述:

I wrote an app where multiple users can edit a database in realtime. I am using socket-io to keep all users' pages up to date with any changes to the database.

All input values broadcast a change.

Say I bind a function to an input's change event:

$(".input-field").change(function(ev) {

codeThatChangesOtherInputValuesOnMyPage1;

codeThatChangesOtherInputValuesOnMyPage2;

codeThatChangesOtherInputValuesOnMyPage3;

codeThatChangesOtherInputValuesOnMyPage4;

codeThatChangesOtherInputValuesOnMyPage5;

codeThatChangesOtherInputValuesOnMyPage6;

codeThatChangesOtherInputValuesOnMyPage7;

codeThatChangesOtherInputValuesOnMyPage8;

var tableColumn = $(ev.target).attr('table-col');

var newFieldValue = $(ev.target).val()

broadcastChange(tableColumn, newFieldValue); // this is pseudo code for a socket-io emit()

});

socket.on('runThisWhenReceivingBroadcastFromServer', function(response) {

// response.data has the input element id of element I should update.

// Get the input field i should update

var theInputField = getInputField(response.data)

$(theInputField).val(getNewInputValue(response.data))

$(theInputField).change();

// I call change because I want all my code in the input's change function to run, except for the last line.

});

I have already fixed this problem, but I am repeating myself by just copying all my code from on change function and pasting it in the broadcast receiving and then just omitting the broadcastChange line. But i want to follow DRY (Don't Repeat Yourself).

Also codeThatChangesOtherInputValuesOnMyPage1; is just that, code. Its tons of code. How would you go about restructuring the code?

My first thought was to do something like this (pseudo code):

$(".input-field").change(function(ev) {

codeThatChangesOtherInputValuesOnMyPage1;

codeThatChangesOtherInputValuesOnMyPage2;

codeThatChangesOtherInputValuesOnMyPage3;

codeThatChangesOtherInputValuesOnMyPage4;

codeThatChangesOtherInputValuesOnMyPage5;

codeThatChangesOtherInputValuesOnMyPage6;

codeThatChangesOtherInputValuesOnMyPage7;

codeThatChangesOtherInputValuesOnMyPage8;

var tableColumn = $(ev.target).attr('table-col');

var newFieldValue = $(ev.target).val()

if (!ev.data.comingFromBroadcastReceiverFunction) {

broadcastChange(tableColumn, newFieldValue); // this is pseudo code for a socket-io emit()

}

});

but you can't pass data to change(); only when binding the function.

What do you guys think is the functional programming approach to this?

网友答案:

If you are copying and pasting code over and over, you could avoid that by separating the duplicate code into a new function, and have both the change and the socket functions call it.

For example, it could work like this:

function updateInputValue(inputField) {
   codeThatChangesOtherInputValuesOnMyPage1;
   codeThatChangesOtherInputValuesOnMyPage2;
   codeThatChangesOtherInputValuesOnMyPage3;
   codeThatChangesOtherInputValuesOnMyPage4;
   codeThatChangesOtherInputValuesOnMyPage5;
   codeThatChangesOtherInputValuesOnMyPage6;
   codeThatChangesOtherInputValuesOnMyPage7;
   codeThatChangesOtherInputValuesOnMyPage8;
}

$(".input-field").change(function(ev) {
   updateInputValue($(ev.target));
   var tableColumn = $(ev.target).attr('table-col');
   var newFieldValue = $(ev.target).val()
   broadcastChange(tableColumn, newFieldValue); // this is pseudo code for a socket-io emit()
});


socket.on('runThisWhenReceivingBroadcastFromServer', function(response) {
    // response.data has the input element id of element I should update.
    // Get the input field i should update
    var theInputField = getInputField(response.data)
    $(theInputField).val(getNewInputValue(response.data))
    updateInputValue($(theInputField));  
    // I call change because I want all my code in the input's change function to run, except for the last line.
});
相关阅读:
Top