Подключаемый модуль jQuery - Глубокая модификация параметров

В настоящее время я работаю над подключаемым модулем с довольно глубокой переменной настроек (в некоторых местах 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 () , потому что это может быть что угодно. Или дайте мне знать, если я параноик, и это не должно вызвать никаких проблем.

6
задан Chad 7 December 2011 в 20:35
поделиться