He separado las funciones JS de diferentes páginas web (índice, inicio de sesión, registro y otras) en sus propios archivos JS que luego se importan al archivo JS principal, que incluye funciones que se comparten en más de una página. He hecho esto con el propósito de mantener y leer el código (espero), de lo contrario tendría cientos de líneas de código en un archivo.

login.js

export function loginSubmit() {
  $("#login-form").submit(function (event) {
    event.preventDefault();
    event.stopPropagation();
    let formValid;

    $("#login-form input").each(function () {
      if ($(this).val() === "") {
        fieldInputInvalid($(this));
        formValid = false;
      }
    });

    if (formValid !== false) {
      // submit the form for authentication
    }
  });
}

register.js

export function loginSubmit() {
  $("#register-form").submit(function (event) {
    event.preventDefault();
    event.stopPropagation();
    let formValid;

    // other form validation functions (not shown as not necessary to post)  

    $("#register-form input").each(function () {
      if ($(this).val() === "") {
        fieldInputInvalid($(this));
        formValid = false;
      }
    });

    if (formValid !== false) {
      // submit the form for user registration
    }
  });
}

main.js

// import all functions from these js files
import * as login from "../scripts/login.js";
import * as register from "../scripts/register.js";

// general functions used on more than one page
function fieldInputInvalid(inputField) {
  // Changes styling of inputField to display to user that it is invalid.
}

function fieldInputValid(inputField) {
  // Changes styling of inputField to display to user that it is valid.
}

function createElement(elemName, elemAttributes) {
  // Create document element
  var elem = document.createElement(elemName);
  // Check if element attirbutes were passed
  if (elemAttributes !== "undefined") {
    // Loop through each argument
    $.each(elemAttributes, function (key, value) {
      // and assign it to the document element
      elem.setAttribute(key, value);
    });
  }
  // Return document element
  return elem;
}

Como puede ver en mis ejemplos de código, tanto las funciones login.js como register.js llaman a la función fieldInputInvalid () de main.js, sin embargo, obtengo el error Uncaught ReferenceError: fieldInputInvalid is not defined cuando se envían cualquiera de los formularios. Sé que puedo solucionar esto poniendo la función fieldInputInvalid tanto en login.js como en register.js, pero pensé que esto rompería la regla de no duplicar el código. ¿Hay alguna manera de hacer que esto funcione con mi estructura actual o una mejor manera de lograr el resultado que deseo?

(NOTA: Tengo muchas otras funciones generales que no están incluidas en esta publicación que se usarían en mi sitio web. Soy consciente de que podría poner el código de login.js y register.js juntos en un archivo llamado identity.js con las funciones fieldInputInvalid y fieldInputValid y luego exportar, pero esto no resolvería ninguna de las otras funciones generales que están incluidas en mi proyecto.

1
JLI_98 26 ago. 2020 a las 20:02

1 respuesta

La mejor respuesta

Declare fieldInputInvalid en su propio archivo, y luego haga que login y register lo importen:

// fieldInputInvalid.js
export const fieldInputInvalid = () => {
  // ...
}
// login.js
import { fieldInputInvalid } from './fieldInputInvalid';
// ...

Otra opción sería, siempre que se llame a loginSubmit, pasarle la función fieldInputInvalid, si puede, por ejemplo:

loginSubmit(fieldInputInvalid);
// login.js (and register.js):
export function loginSubmit(fieldInputInvalid) {
  // ...

Entonces podrás llamar a fieldInputInvalid dentro de loginSubmit.

Si tiene varias funciones compartidas y no desea pasar cada una individualmente, también puede pasar un objeto de funciones a todos los loginSubmit s, como:

loginSubmit({ fieldInputInvalid, someOtherHelper });
// login.js (and register.js):
export function loginSubmit({ fieldInputInvalid, someOtherHelper }) {
  // ...
1
CertainPerformance 26 ago. 2020 a las 17:07