2010-03-26 7 views
11

Digamos que yo quiero hacer estoañadiendo a la propiedad JSON que puede o no existir todavía

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

me sale un error que dice 'no está definida dashboard.pages'

está ahí fuera para añadir dinámicamente 'páginas' y los niños que siguen sin tener que hacer el trabajo de comprobación para ver si se define primero y luego si no es haciendo

dashboard['pages'] = {}; 

porque a veces pueden existir ya y yo no quiero VHA e inspeccionar el árbol primero sólo quiero construir las ramas como sea necesario

EDITAR cambié 'nombre de la página' a la página para mostrar que los nombres de las páginas cambiarán y alo quiero señalar que las páginas podrían ser realmente cualquier cosa también la idea es que tenga cualquier objeto que pueda contener ojbjecs con parámetros sin verificar si existen las ramas

Parece que $ extender como se indicó será el camino a seguir simplemente no estoy seguro de cómo funciona. que conseguir mi cabeza alrededor de ese

+0

lo siento - la la secuencia de comandos no tiene sentido para mí. El uso de indexadores de corchetes implica el deseo de indexar dinámicamente el objeto, pero está usando constantes. Eso, combinado con la afirmación de que "no quieres hacer el trabajo" me hace preguntarme si sabes lo que estás tratando de lograr. No trato de denigrar, solo una observación de por qué es posible que no obtengas la respuesta que estás buscando. –

Respuesta

13

Defina los métodos get y set en un Object. En realidad, podría definirse solo en el objeto dashboard y solo sus descendientes, pero eso es fácil de hacer.

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

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

iterar a través de propiedades anidada utilizando este método get() y llame set() cuando un valor tiene que ser establecido.

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

También podría ampliar/modificar el método get para aceptar las propiedades anidadas como argumentos individuales o una matriz o una cadena. El uso de eso, sólo tendría que llamar a conseguir una vez:

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

actualización:

Dado que el método get devuelve un objeto de forma genérica y no sabe si necesita una matriz o algún otro tipo de objeto, por lo que tendría que especificar que ustedes mismos:

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

entonces usted podría empujar los artículos a la matriz ajustes como

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

Para que realmente la función get construya la jerarquía de objetos a partir de una cadena dada como pages.user, debería dividir la cadena en partes y verificar si existe cada objeto anidado. Aquí es una versión modificada de get que hace precisamente eso:

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

bien, esto parece lo que estaba pidiendo, excepto que no estoy usando un prototipo, ¿cómo haré esto en jquery? también déjame dar un paso más, digamos que quiero hacerlo, así que tengo dashboard.get ('pages.user.settings'). push ("algo"); dashboard.get ('pages.user.settings'). Push ("somethingelse"); que debería darme dos elementos en la configuración ¿no? – mcgrailm

+0

@mmcgrail, esto es Javascript regular y no el marco Prototype. El primer enfoque para obtener cada propiedad debería funcionar en cada navegador (no se necesita jquery para eso). Actualizando la respuesta para la otra consulta. – Anurag

+0

¡eso es asombroso! He aprendido mucho de esto, gracias – mcgrailm

0

$ .extend es el camino a seguir

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

Pero honestamente - esta es una idea bastante desordenado para almacenar esta información de todos modos. apuesto a que si necesita información más adelante que se podría hacer con un buen selector o con jQuery.data()

+0

pero eso no es dinámico definiendo el json en la función. Examinaré las otras sugerencias que tiene – mcgrailm

+0

No, estoy construyendo un objeto que tiene solo un elemento y lo fusiono en la variable de datos. Hace lo mismo Su código si funcionó, pero también funciona cuando su código no lo hizo. Todavía estoy contento de que lo intentes de una manera diferente :) – naugtur

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

Explicación: la primera línea comprobará si el primer valor es nulo, indefinido o .. . false (no creo que esto sea un problema aquí): si lo es, cree un nuevo objeto, si no es así, lo usará.

1

No creo que haya una buena forma integrada de hacerlo, pero siempre se puede abstraer con una función.

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

continuación, utiliza

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

o

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

Como se ha mencionado, $ .extend hará que esto sea menos gravosa.

2

lo haría con el operador ternario:

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

que va a hacer el truco, no importa si está configurado/nulo o lo que sea.

0

Bueno, supongo que necesita esto:

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

Parece que se trata de XML.

0

La mejor solución para mi caso era hacer un prototipo de objetos

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

y entonces usted puede obtener su propiedad como esta

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

espero que ayude :)

Cuestiones relacionadas