В настоящее время я работаю над подключаемым модулем с довольно глубокой переменной настроек (в некоторых местах 3-4 уровня). Следуя общепринятому шаблону подключаемого модуля jQuery, я реализовал простой способ для пользователей изменять настройки на лету, используя следующую нотацию:
$('#element').plugin('option', 'option_name', 'new_value');
Вот код, аналогичный тому, который я использую сейчас для метода параметров.
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;
}
Теперь учтите, что у меня есть такая переменная настроек:
var settings = {
opt: false,
another: {
deep: true
}
};
Если я хочу изменить настройки deep
, я должен использовать следующую запись:
$('#element').plugin('option', 'another', { deep: false });
Однако, поскольку на практике мои настройки могут быть 3-4 уровня в глубину, я считаю, что следующие обозначения были бы более полезными:
$('#element').plugin('option', 'another.deep', false);
Однако я не уверен, насколько это возможно и как это сделать. В качестве первой попытки я попытался «пройти» к рассматриваемой опции и установить ее, но если я установил свою переменную обхода, она не установила то, на что она ссылается в исходной переменной настроек.
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;
}
Другими словами: если установить opt
после обхода, параметр, на который он фактически ссылается в переменной settings
, не изменится после выполнения этого кода.
Прошу прощения за длинный вопрос, любая помощь приветствуется. Спасибо!
РЕДАКТИРОВАТЬ
В качестве второй попытки я могу сделать это с помощью eval ()
вот так:
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;
}
Но я действительно хотел бы посмотреть, сможет ли кто-нибудь показать мне способ не используйте eval. Поскольку это строка ввода пользователя, я бы предпочел не запускать для нее eval ()
, потому что это может быть что угодно. Или дайте мне знать, если я параноик, и это не должно вызвать никаких проблем.