2012-01-09 19 views
16

AJAX kullanırken, nesneleri sunucudan Javascript'e JSON nesneleri (aka Javascript) biçiminde geçirme eğilimindeyim. Javascript'in içindeki bazı işlevler kullandığım belirli nesne türüne güveniyor. Örneğin, örneğin bir telefon numarası kullanalım. Bir kurucu var: Javascript'te bir telefon numarası nesnesi oluştururken kullandım. Bazı durumlarda, JS'de nesneyi oluşturmuyorum, nesneyi sunucudan alıyorum, böylece aynı alanlara sahip genel bir nesne biçiminde geliyor. Benim kod bunun gibi bir şey kullanarak belirli tipine dayanır ne zaman:JSON Nesneleri Javascript nesnelerine eşleme

var objType = objArray[i].constructor.name; 
var mappedObj; 

switch(objType) { 
    case 'PhoneNumber': 
     currentArray = currentArray.phone; 
     //Convert response to javascript object. 
     mappedObj = mapPhone(jsonResponse[i]); 
     break; 
    case 'Email': 
     currentArray = currentArray.email; 
     mappedObj = mapEmail(jsonResponse[i]); 
     break; 
    case 'Address': 
     currentArray = currentArray.address; 
     mappedObj = mapAddress(jsonResponse[i]); 
     break; 
    case 'Website': 
     currentArray = currentArray.website; 
     mappedObj = mapWebsite(jsonResponse[i]); 
} 

Bu durumda, ben nesneleri yapıcı adını ve o adına göre ayarlanmış belirli değişkenleri kontrol edin. İsmi kontrol ettiğim nesne sunucudan bir JSON ise, bana genel bir "Nesne" yanıtı verir ve bu nedenle kod çalışmaz.

function mapPhone(phoneObj) { 
    var id = phoneObj.id; 
    var contactId = phoneObj.contactId; 
    var number = phoneObj.number; 
    var type = phoneObj.type; 
    var primary = phoneObj.isPrimary; 
    var className = phoneObj.className; 
    var phoneNumber = new PhoneNumber(number, type, primary, contactId, id, className); 
    return phoneNumber; 
} 

Bu gayet güzel çalışıyor, ama bana biraz gereksiz görünüyor: Ben gibi nesne her biri için bir eşleştirme işlevini kullanarak bu sorunu olsun. JSON Nesne sorununu çözmenin en iyi yolu bu mu yoksa daha iyi bir çözüm var mı? Bunun daha çok "Bunu mümkün olan en iyi şekilde yapıyorum" türünden bir soru olduğunu anlıyorum, ama Javascript kodumda bu mantıksal mantığı DOĞRULAYI tekrar ediyorum. Bunu yapmanın en doğru yolu, saatte saatte sabitlemem gerekiyor.

DÜZENLEME: jQuery çözümünü kabul ettim çünkü jQuery'yi projemde kullanıyorum. Bununla birlikte jQuery seçeneğini bulmadan önce benim için de çalışan çok sayıda çözüm var. Onlar sadece temiz ve verimli değildi.

+4

* "JSON nesneleri (aka JavaScript)" * JSON aka JavaScript değildir. Kendi adı ve özniteliği olduğu için kendi adı vardır. –

cevap

25

Aşağıdakiler, nesnenizde ve JSON nesnesinde aynı özelliklere sahip olmanızı gerektirir.

var phoneNumber = $.extend(new PhoneNumber(), yourJSONObject); 

Bu temelde yeni bir PhoneNumber nesnesi oluşturur ve daha sonra tüm özelliklerini JSON nesnesinden üzerine kopyalar. $.extend() yöntemi jQuery'den kaynaklanır, ancak benzer yöntem olarak örn. Underscore.js veya diğer js kütüphaneleri/çerçevelerinden biri.

+0

jQuery'yi kullanıyorum, bu yüzden bu bir benim için bile daha kolay bir çözüm. – ryandlf

+3

Köşeli olarak kullanırsanız, 'var phoneNumber = angular.copy (sizinJSONObject, yeni PhoneNumber())' komutunu kullanabilirsiniz. Bu sözdizim doğru olmayabilir, ama yapabilirsin, ve istediğin fonksiyon bu! – Chris

+1

Açısal olarak, angular.copy(), angular.extend() veya angular.merge() öğesini kullanabilirsiniz. Kopyala, yeni nesnenizin özelliklerini şeritler ve sonra kaynak nesnenin özelliklerini klonlar. Yeni nesnenin mevcut özelliklerini korurken, genişlet ve birleştir, kaynak nesnenin özelliklerini yeni nesneye (sırasıyla sığ ve derin kopya) getirir. http://davidcai.github.io/blog/posts/copy-vs-extend-vs-merge/ – Nhan

1

Eski tarayıcıları desteklemiyorsanız, için eşlemeyi Object.create kullanabilirsiniz.

DEMO

function makeThisExtend(obj, CtorFunc) { 
    for (var k in obj) 
     if ({}.hasOwnProperty.call(obj, k)) 
      obj[k] = { value: obj[k] }; 

    return Object.create(CtorFunc.prototype, obj); 
} 

var objFromServer = { Number: "123", id: 5 }; 
objFromServer = makeThisExtend(objFromServer, PhoneNumber); 


alert(objFromServer.Number + " " + objFromServer.id); //123 5 
alert(objFromServer.constructor); //function PhoneNumber ... 
2

AFAIK, yani her şeyde (MDN-in o şim ikinci parametresini kabul etmediğinden, eski tarayıcıları düzeltin. Değil edecek de pul-en azından şimi bırakarak) IE, bunu yapabilirsiniz:

// define a class 
var Foo = function(name) { 
    this.name = name; 
} 
// make a method 
Foo.prototype.shout = function() { 
    return "I am " + this.name; 
} 
// make a simple object from JSON: 
var x = JSON.parse('{ "name": "Jason" }'); 
// force its class to be Foo 
x.__proto__ = Foo.prototype; 
// the method works 
x.shout(); 

Maalesef IE __proto__ erişimci desteklemez, bu nedenle ilk olarak nesnenin boş örneğini oluşturmak yapmanız gereken ne, o zaman sadece polis y Her şey bittikten:

// make a simple object from JSON: 
var x = JSON.parse('{ "name": "Jason" }'); 
// make an empty Foo 
var y = Object.create(Foo.prototype); 
// copy stuff over 
for (a in x) { 
    y[a] = x[a]; 
} 
y.shout(); 

Bu yaklaşımların her ikisi KURU tutarak biraz daha genel senin mapWhatever fonksiyonlarından daha vardır.

+0

Temiz bir çözüm gibi görünüyor. Aradığım şey bu, teşekkürler. Testlerimin çalıştığını varsayarsak, bu kabul edilmiş bir cevaba benziyor. – ryandlf

+1

Amadan'ın cevabını yazmasından iki yıl sonra reddetti. Bu, kullanımdan kaldırıldığı için __proto__ kullanarak prototipe asla erişmemelidir: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto –

3

Bu benzer soru ilginç cevaplar bir yeri vardır:

function recastJSON(jsonObject) { 
    // return generic object if objectType is not specified 
    if (!jsonObject.objectType) 
     return jsonObject; 

    // otherwise create a new object of type specified 
    var obj = eval('new '+jsonObject.objectType+'()'); 
    for(var i in jsonObject) 
     obj[i] = jsonObject[i]; 
    return obj; 
} 

You will:

Parse JSON String into a Particular Object Prototype in JavaScript

Yazarın kendi cevap kapalı göre, bunun senin için etkili bir çözüm olacağını düşünüyorum örneklemek istediğiniz javascript sınıfını tanımlamak için aldığınız JSON nesnelerine objectType eklemeniz gerekir. Ardından bu işlevi çağırdığınızda, nesneyi bu türe atar ve verileri ('objectType' değişkenini de içerecek şekilde) kopyalayacaktır. Telefon numaranız örneği kullanarak

, kod aşağıdaki gibi görünecektir:

// generic object from JSON 
var genericObject = {objectType:'PhoneNumber', number:'555-555-5555', type:'home', primary:true, contactId:123, id:1234, className:'stdPhone'}; 
var phoneObject = recastJSON(genericObject); 
İlgili konular