2010-03-26 15 views
11

diciamo che voglio fare questoaggiungendo alla proprietà JSON che possono o non possono esistere ancora

var dasboard = {}; 
    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'; 
    }); 
    } 

ottengo un errore che dice 'dashboard.pages è indefinito'

c'è via per aggiungere dinamicamente 'pagine' ei bambini che seguono, senza dover fare il lavoro di controllo per vedere se è definito prima poi se non fare

dashboard['pages'] = {}; 

perché a volte possono già esistere e io non voglio hav e per ispezionare l'albero prima voglio solo per costruire i rami come necessario

EDIT ho cambiato 'nomepagina' alla pagina per mostrare che i nomi di pagina cambieranno e alo voglio sottolineare che le pagine potrebbero essere davvero anche niente l'idea è che si dispone di qualsiasi oggetto che può contenere ojbjecs con parametri senza verificare se i rami esistono

sembra $ est come dichiarato sarà il modo di andare solo non è sicuro di come funziona. avuto modo di ottenere la mia testa intorno che

+0

dispiace - la la sceneggiatura non ha senso per me. L'uso degli indicizzatori di parentesi implica il desiderio di indicizzare dinamicamente l'oggetto, ma si utilizzano costanti. Ciò, combinato con l'affermazione che "non vuoi fare il lavoro", mi chiede se tu sappia cosa stai cercando di realizzare. Non cercare di denigrare - solo un'osservazione sul motivo per cui potresti non ottenere la risposta che stai cercando. –

risposta

13

Definire i metodi get e set su un Object. In realtà potrebbe essere definito solo sull'oggetto dashboard e solo i suoi discendenti, ma è facile da fare.

Object.prototype.get = function(prop) { 
    this[prop] = this[prop] || {}; 
    return this[prop]; 
}; 

Object.prototype.set = function(prop, value) { 
    this[prop] = value; 
} 

Scorrere proprietà nidificate utilizzando questo metodo get() e chiamare set() ogni volta che un valore deve essere impostato.

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"}}}; 

Si potrebbe anche estendere/modificare il metodo get per accettare le proprietà nidificate come singoli argomenti o un array o una stringa. Usando questo, si avrebbe solo chiamare ottenere una volta:

// 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'; 

Aggiornamento:

Dato che il metodo get genericamente restituisce un oggetto e non sa se avete bisogno di un array o qualche altro tipo di oggetto, in modo da dovrebbe specificare che voi stessi:

dashboard.get('pages.user').settings = []; 

allora si potrebbe spingere gli elementi alla matrice impostazioni come

dashboard.get('pages.user').settings.push('something'); 
dashboard.get('pages.user').settings.push('something else'); 

Per fare in modo che la funzione get costruisca la gerarchia di oggetti da una stringa specifica come pages.user, è necessario suddividere la stringa in parti e verificare se esiste ogni oggetto nidificato. Ecco una versione modificata di get che fa proprio questo:

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'); 
+0

ok questo assomiglia a quello che stavo chiedendo tranne che non sto usando il prototipo come farei questo in jQuery? lasciatemi fare un ulteriore passo avanti, diciamo che voglio farlo in modo che io abbia dashboard.get ('pages.user.settings'). push ("qualcosa"); dashboard.get ('pages.user.settings'). Push ("somethingelse"); che dovrebbe darmi due elementi nelle impostazioni giusto? – mcgrailm

+0

@mmcgrail, questo è Javascript regolare e non il framework Prototype. Il primo approccio per ottenere ogni proprietà dovrebbe funzionare su ogni browser (jquery non è necessario per quello). Aggiornamento della risposta per l'altra query. – Anurag

+0

è fantastico! Ho imparato da questo, grazie – mcgrailm

0

$ .extend è la strada da percorrere

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')); 

Ma onestamente - questa è un'idea piuttosto disordinato per memorizzare queste informazioni in ogni caso. Scommetto che se hai bisogno che le informazioni in seguito potrebbe essere fatto con un buon selettore o con jQuery.data()

+0

ma non è dinamico il tuo definire il json nella funzione. Vedrò gli altri suggerimenti che hai – mcgrailm

+0

No, sto costruendo un oggetto che ha un solo elemento e lo uniamo alla variabile dati. Fa la stessa cosa che ha fatto il tuo codice se ha funzionato, ma funziona anche quando il tuo codice non funziona. Comunque sono contento che tu provi in ​​un modo diverso :) – naugtur

0
var foo = dashboard['pages'] || {}; 
foo['pagename'] = 'your thing here'; 
dashboard['pages'] = foo; 

Spiegando: la prima linea verificherà se il primo valore è nullo, non definito o .. . false (non pensare che questo sia un problema qui): se lo è, crea un nuovo oggetto, se non lo è, lo userà.

1

Non penso che ci sia un buon modo integrato per farlo, ma è sempre possibile estrapolarlo con una funzione.

function getProperty(obj,prop){ 
    if(typeof(obj[prop]) == 'undefined'){ 
     obj[prop] = {}; 
    } 
    return obj[prop]; 
} 

quindi si utilizza

getProperty(dashboard,'pages')['pagename']

o

getProperty(getProperty(dashboard,'pages'),'pagename'); 

Come accennato, $ .extend renderà questo meno pesante.

2

lo farei con l'operatore ternario:

dashboard['pages'][page] = dashboard['pages'][page] ? dashboard['pages'][page] : {}; 

Che farà il trucco, non importa se è impostato/null o qualsiasi altra cosa.

0

Beh immagino avete bisogno di questo:

var dashBoard = new Array(); 
if(!dashboard['page123']) { 
    dashBoard.push('page123'); 
} else { 
...do what you want 
} 

Sembra avete a che fare con XML.

0

La soluzione migliore per il mio caso è stato quello di fare un prototipo oggetto

/** 
* 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; 
}; 

e quindi è possibile ottenere la vostra proprietà come questa

var object = {step1:{step2:{step3:'test'}}} 
Object.get(object, 'step1.step2.step3'); // return 'test' 

Speranza che aiuta :)

Problemi correlati