Добавление свойства json, которое может или не может существовать
скажем, я хочу это сделать:
var dashboard = {};
var page = "index";
$('.check').click(function(){
$(this).toggleClass("active").siblings().slideToggle('slow', function() {
dashboard['pages'][page][$(this).closest('li').attr("id")]['show'] = $(this).is(":hidden") ? 'collapsed' : 'expanded';
});
}
Я получаю сообщение об ошибке:
Dashboard.pages не определено
Есть ли возможность динамически добавлять pages
и последующие дети, не выполняя работу по проверке, чтобы убедиться, что она определена сначала, а затем, если она не выполняется:
dashboard['pages'] = {};
потому что иногда они могут уже существовать, и я не хочу проверять дерево сначала, я просто хочу построить ветки по мере необходимости
EDIT Я изменил pagename
на page
чтобы показать, что имена страниц будут изменены, а также я хочу указать, что страницы действительно могут быть чем-то другим. Идея состоит в том, что у вас есть объект, который может содержать объекты с параметрами без проверки наличия ветвей
Похоже, что $extend
как указано, будет способом просто не знать, как это работает. Получил свою голову вокруг этого.
Ответы
Ответ 1
Определите методы get и set на Object
. На самом деле его можно было определить только на объекте dashboard
и только его потомках, но это легко сделать.
Object.prototype.get = function(prop) {
this[prop] = this[prop] || {};
return this[prop];
};
Object.prototype.set = function(prop, value) {
this[prop] = value;
}
Итерировать через вложенные свойства, используя этот метод get()
, и вызвать set()
всякий раз, когда значение должно быть установлено.
var dashboard = {};
dashboard.get('pages').get('user').set('settings', 'oh crap');
// could also set settings directly without using set()
dashboard.get('pages').get('user').settings = 'oh crap';
console.log(dashboard); // {pages: {user: {settings: "oh crap"}}};
Вы также можете расширить/изменить метод get
, чтобы принять вложенные свойства в виде отдельных аргументов или массива или строки. Используя это, вам нужно будет только один раз вызвать:
// get accepts multiple arguments here
dashboard.get('pages', 'user').set('settings', 'something');
// get accepts an array here
dashboard.get(['pages', 'user']).set('settings', 'something');
// no reason why get can't also accept dotted parameters
// note: you don't have to call set(), could directly add the property
dashboard.get('pages.user').settings = 'something';
Обновление
Поскольку метод get обычно возвращает объект и не знает, нужен ли вам массив или какой-либо другой тип объекта, поэтому вам нужно будет указать, что вы сами:
dashboard.get('pages.user').settings = [];
Затем вы можете нажимать элементы в массив настроек как
dashboard.get('pages.user').settings.push('something');
dashboard.get('pages.user').settings.push('something else');
Чтобы иметь функцию get, построить иерархию объектов из заданной строки, такой как pages.user, вам придется разделить строку на части и проверить, существует ли каждый вложенный объект. Вот модифицированная версия get
, которая делает именно это:
Object.prototype.get = function(prop) {
var parts = prop.split('.');
var obj = this;
for(var i = 0; i < parts.length; i++) {
var p = parts[i];
if(obj[p] === undefined) {
obj[p] = {};
}
obj = obj[p];
}
return obj;
}
// example use
var user = dashboard.get('pages.user');
user.settings = [];
user.settings.push('something');
user.settings.push('else');
console.log(dashboard); // {pages: {user: {settings: ["something", "else"] }}}
// can also add to settings directly
dashboard.get('pages.user.settings').push('etc');
Ответ 2
Я бы сделал это с помощью тернарного оператора:
dashboard['pages'][page] = dashboard['pages'][page] ? dashboard['pages'][page] : {};
Это сделает трюк, независимо от того, установлен ли он /null или что-то еще.
Ответ 3
Я не думаю, что есть хороший встроенный способ сделать это, но вы всегда можете абстрагировать его с помощью функции.
function getProperty(obj,prop){
if( typeof( obj[prop] ) == 'undefined' ){
obj[prop] = {};
}
return obj[prop];
}
Затем вы используете
getProperty(dashboard,'pages')['pagename']
или
getProperty(getProperty(dashboard,'pages'),'pagename');
Как уже упоминалось, $.extend сделает это менее обременительным.
Ответ 4
Лучшее решение для моего случая было сделать прототип объекта
/**
* OBJECT GET
* Used to get an object property securely
* @param object
* @param property
* @returns {*}
*/
Object.get = function(object, property) {
var properties = property.split('.');
for (var i = 0; i < properties.length; i++) {
if (object && object[properties[i]]) {
object = object[properties[i]];
}
else {
return null;
}
}
return object;
};
И тогда вы можете получить свою собственность, как это
var object = { step1: { step2: { step3: ['value1', 'value2'] }}}
Object.get(object, 'step1.step2.step3'); // ['value1', 'value2']
Object.get(object, 'step1.step2.step3.0'); // 'value1'
Object.get(object, 'step1.step2.step3.step4'); // null
Надеюсь, поможет :)
Ответ 5
$. extend - это путь
function elem(a,b){
var r={'pages':{'pagename':{}}};
r.pages.pagename[a]={'show':b};
return r;
}
data={};
//inside the event handler or something:
data = $.extend(true,data,elem($(this).closest('li').attr("id"),$(this).is(":hidden") ? 'collapsed' : 'expanded'));
Но честно говоря - это довольно грязная идея хранить эту информацию в любом случае.
Бьюсь об заклад, если вам понадобится эта информация позже, это может быть сделано с хорошим селектором или с jQuery.data()
Ответ 6
var foo = dashboard['pages'] || {};
foo['pagename'] = 'your thing here';
dashboard['pages'] = foo;
Объяснение: первая строка будет проверять, имеет ли первое значение значение null, undefined или... false (не думайте, что это проблема здесь): если это так, создайте новый объект, если он не является, будет использовать его.
Ответ 7
Ну, я думаю, вам это нужно:
var dashBoard = new Array();
if(!dashboard['page123']) {
dashBoard.push('page123');
} else {
...do what you want
}
Кажется, вы имеете дело с XML.
Ответ 8
Если вы используете подчеркивание> = 1.9.0, вы можете использовать property
и propertyOf
:
d={a: {b: "c"}}
_.property(["a", "b", "c", "e"])(d) // undefined
_.property(["a", "b"])(d) // "c"
_.propertyOf(d)(["a", "b", "c", "e"]) // undefined
_.propertyOf(d)(["a", "b"]) // "c"