Estoy un poco perplejo en este. Me gustaría pasar un objeto a otra función cuando hago clic en un botón. De esa manera puedo trabajar con el objeto en la función final.
En este ejemplo, me gustaría pasar el objeto del automóvil de la función renderCar a la función makeEditable cuando hago clic en el botón Editar.
Lo que probé:
<button onclick="makeEditable(${car})">Edit</button>
<button onclick="makeEditable(car)">Edit</button>
<button onclick="makeEditable('${car}')">Edit</button>
Puedo pasar una cadena como
<button onclick="makeEditable('${car.type}')">Edit</button>
pero sin éxito al pasar todo el objeto.
Aquí escribí un ejemplo de lo que estoy buscando hacer.
Violín: https://jsfiddle.net/kyleteeter/v8gs05e1/10/
HTML
<div id="root" ></div>JS
let cars = [ { "color": "purple", "type": "minivan", "capacity": 7 }, { "color": "red", "type": "station wagon", "capacity": 5 } ] cars.map(car => { this.root.innerHTML += this.renderCar(car) }); function renderCar(car) { return `<div><div data-type="color">${car.color}</div><div data-type="type">${car.type}</div><div data-type="capacity">${car.capacity}</div><button onclick="makeEditable('${car}')">Edit</button></div>` } function makeEditable(car){ console.log(car) }El problema se vuelve bastante evidente si miras el HTML generado. En él, tendrá '[object Object]' solo porque eso es lo que sucede si intenta convertir un objeto en una cadena, y es algo obvio que desde este punto no puede llamar a makeEditable() y esperar el objeto para volver a aparecer mágicamente: termina llamando a la función con '[object Object]' como argumento y, bueno, este no es el objeto que está buscando.
Estoy viendo dos enfoques posibles:
function renderCar(car) { return `<div><div data-type="color">${car.color}</div><div data-type="type">${car.type}</div><div data-type="capacity">${car.capacity}</div><button onclick="makeEditable('${encodeURI(JSON.stringify(car))}')">Edit</button></div>`; } ... luego, para recuperarlo correctamente, tendría que revertir el proceso en la función makeEditable() :
function makeEditable(data) { let car = JSON.parse(decodeURI(data)); console.log(car); }... pero eso es un poco feo y puede que no siempre funcione.
Editar: el enfoque anterior usando btoa() y atob() (en lugar de encodeURI(JSON.stringify() y luego JSON.parse(decodeURI(data)) respectivamente) podría ser mejor si sigue esta ruta, simplemente no había pensado de eso al momento de escribir.
let cars = [ { color: "purple", type: "minivan", capacity: 7, id: "2a93d4e1-9ee9-4490-b4a8-da836cf81d7f", }, { color: "red", type: "station wagon", capacity: 5, id: "aa207e90-08d1-434f-afeb-aed1dbd1dab9", } ]; cars.map((car) => { this.root.innerHTML += this.renderCar(car); }); function renderCar(car) { return `<div><div data-type="color">${car.color}</div><div data-type="type">${car.type}</div><div data-type="capacity">${car.capacity}</div><button onclick="makeEditable('${car.id}')">Edit</button></div>`; } function findById(id, array) { return array.find((e) => e.id === id); } function makeEditable(id) { let car = findById(id, cars); console.log(car); }Creo que puede crear un fragmento de documento o simplemente un elemento y adjuntarle los detectores de eventos. Así tendrás más agilidad para pasar cualquier tipo de argumento.
Sin embargo, si realmente desea que funcione de la manera en que lo ha intentado, considere el siguiente ejemplo.
Diría que su implementación es exagerada, pero funciona.
Básicamente, cualquier parámetro pasado de esta manera se convertirá en una cadena (porque está entre comillas). Para aprovecharlo, puede secuenciar su objeto y codificarlo en base64 (para mantenerlo como una cadena), y en la función de destino simplemente decodificarlo y analizarlo de la misma manera.
const cars = [ { color: 'purple', type: 'minivan', capacity: 7, }, { color: 'red', type: 'station wagon', capacity: 5, }, ]; cars.forEach((car) => { this.root.innerHTML += renderCar(car); }); function makeEditable(car) { const parsed = JSON.parse(atob(car)); console.log(parsed); } function renderCar(car) { const stringified = btoa(JSON.stringify(car)); return ` <div> <div data-type='color'>${car.color}</div> <div data-type='type'>${car.type}</div> <div data-type='capacity'>${car.capacity}</div> <button onclick="makeEditable('${stringified}')">Edit</button> </div> `; } <div id="root"></div>