Actualmente estoy trabajando en un complemento con una variable de configuración bastante profunda (3-4 niveles en algunos lugares). Siguiendo el patrón de jQuery Plugin generalmente aceptada he implementado una forma sencilla para que los usuarios modificar los ajustes sobre la marcha utilizando la siguiente notación:Complemento jQuery - Modificación de opción profunda
$('#element').plugin('option', 'option_name', 'new_value');
Este es el código similar a lo que estoy utilizando ahora para el método de opciones.
option: function (option, value) {
if (typeof (option) === 'string') {
if (value === undefined) return settings[option];
if(typeof(value) === 'object')
$.extend(true, settings[option], value);
else
settings[option] = value;
}
return this;
}
Ahora considero que tengo una variable de configuración de este modo:
var settings = {
opt: false,
another: {
deep: true
}
};
Si quiero cambiar las deep
ajustes que tiene que utilizar la siguiente notación:
$('#element').plugin('option', 'another', { deep: false });
Sin embargo, ya que en la práctica mis configuraciones pueden tener 3-4 niveles de profundidad, creo que la siguiente notación sería más útil:
$('#element').plugin('option', 'another.deep', false);
Sin embargo, no estoy seguro de cuán factible es esto ni de cómo hacerlo. Como primer intento, traté de "atravesar" la opción en cuestión y configurarla, pero si configuro la variable de desplazamiento, no establece a qué se refiere en la variable de configuración original.
option: function (option, value) {
if (typeof (option) === 'string') {
if (value === undefined) return settings[option];
var levels = option.split('.'),
opt = settings[levels[0]];
for(var i = 1; i < levels.length; ++i)
opt = opt[levels[i]];
if(typeof(value) === 'object')
$.extend(true, opt, value);
else
opt = value;
}
return this;
}
Decir que de otra manera: Al establecer opt
después de atravesar, el ajuste en realidad se refiere a la variable settings
no ha cambiado después de este código se ejecuta.
Pido disculpas por la larga pregunta, cualquier ayuda es apreciada. ¡Gracias!
EDITAR
Como un segundo intento puedo hacerlo usando eval()
así:
option: function (option, value) {
if (typeof (option) === 'string') {
var levels = option.split('.'),
last = levels[levels.length - 1];
levels.length -= 1;
if (value === undefined) return eval('settings.' + levels.join('.'))[last];
if(typeof(value) === 'object')
$.extend(true, eval('settings.' + levels.join('.'))[last], value);
else
eval('settings.' + levels.join('.'))[last] = value;
}
return this;
}
Pero realmente me gustaría ver si alguien me puede mostrar una forma de no use eval. Como es una cadena de entrada de usuario, prefiero no ejecutar eval()
porque podría ser cualquier cosa. O avíseme si estoy siendo paranoico y no debería causar ningún problema.
Fantástico, la confusión en las referencias era lo que nublaba el problema. Gracias por aclarar eso para mí; Tengo un método de trabajo ahora gracias a tu respuesta. – Chad