Attualmente sto lavorando un plugin con una variabile impostazioni che è abbastanza profonda (3-4 livelli in alcuni posti). Seguendo il modello di jQuery Plugin generalmente accettato ho implementato un modo semplice per gli utenti di modificare le impostazioni al volo usando la seguente notazione:jQuery Plugin - modifica di queste opzioni profonda
$('#element').plugin('option', 'option_name', 'new_value');
Ecco il codice simile a quello che sto usando ora il metodo di opzioni.
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;
}
Consideriamo ora che ho una variabile impostazioni in questo modo:
var settings = {
opt: false,
another: {
deep: true
}
};
Se voglio cambiare le deep
impostazioni devo usare la seguente notazione:
$('#element').plugin('option', 'another', { deep: false });
Tuttavia, dato che in pratica le mie impostazioni possono essere di 3-4 livelli di profondità mi sento la seguente notazione sarebbe più utile:
$('#element').plugin('option', 'another.deep', false);
Tuttavia io non sono sicuro di come fattibile questo è, né come fare per farlo. Come primo tentativo ho provato a "attraversare" l'opzione in questione e impostarla, ma se imposto la mia variabile di attraversamento non imposta ciò che fa riferimento nella variabile delle impostazioni originale.
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;
}
Per dire che un altro modo: Impostando opt
dopo aver attraversato, l'impostazione si riferisce in realtà al variabile settings
è invariata dopo questo codice viene eseguito.
Mi scuso per la lunga domanda, ogni aiuto è apprezzato. Grazie!
EDIT
Come secondo tentativo posso farlo utilizzando eval()
in questo modo:
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;
}
Ma mi piacerebbe davvero vedere se qualcuno mi può mostrare un modo per non usare eval. Poiché si tratta di una stringa di input dell'utente, preferirei non eseguire eval()
su di esso perché potrebbe essere qualsiasi cosa. Oppure fammi sapere se sono paranoico e non dovrebbe causare alcun problema.
Fantastico, la confusione sui riferimenti c'era ciò che stava offuscando il problema. Grazie per averlo chiarito; Ho un metodo di lavoro ora grazie alla tua risposta. – Chad