2013-06-28 5 views
1

У меня есть следующий код:jQuery переменная scope? говорит, что не определено

function postToDrupal(contacts, source, owner) { 
    (function ($) { 

    var contact, name, email, entry; 
    emails = {}; 

    for (var i = 0; i < contacts.length; i++) { 
     contact = contacts[i]; 
     emails[i]['name'] = contact.fullName(); 
     emails[i]['email'] = contact.selectedEmail(); 
    } 

    $.post("/cloudsponge-post",emails,function(data) { 

    }); 
    }(jQuery)); 
} 

Я получаю следующее сообщение об ошибке, когда я пытаюсь запустить его:

WARN: Attempt to invoke callback [afterSubmitContacts] failed: TypeError: Cannot set property 'name' of undefined 

Я не уверен, что проблема IS-я вполне новый для JS и нахожу это немного сложнее. Какая причина, по которой она сломана, и как мне ее исправить?

+1

Ваши электронные письма в объекте, а не в массиве, поэтому электронные письма [i] не определены. Также вы забыли var перед ним. – Virus721

+2

Я могу вспомнить, что был вынужден сделать = {} перед установкой свойств объектов, поэтому я предположил, что он одинаковый для массивов. – Virus721

+0

Помните, если я спрашиваю, зачем использовать IIFE непосредственно внутри функции? Функция создает свою собственную область. Это связано с Drupal с использованием переменной '$'? – Jasper

ответ

3

Есть куча способов, которыми вы могли бы написать этот код, но лично я хотел бы сделать это:

function postToDrupal(contacts, source, owner) { 
    // TODO: source and owner are unused 

    var emails = jQuery.map(contacts, function(contact) { 
     return { 
      name: contact.fullName(), 
      email: contact.selectedEmail() 
     } 
    }); 

    jQuery.post('/cloudsponge-post', emails, function(data) { 
     // ... 
    }); 
} 
2

Этот объект emails[i] еще не определен. попробуйте таким образом:

for (var i = 0; i < contacts.length; i++) { 
    contact = contacts[i]; 
    emails[i] = {}; //Instantiate it here 
    emails[i]['name'] = contact.fullName(); 
    emails[i]['email'] = contact.selectedEmail(); 
} 
+0

Я бы не использовал объект для хранения списка. Я предлагаю изменить объявление электронной почты в массив. –

+1

@MarlonBernardes: У него строковые ключи. Это должен быть объект. Почему он должен использовать массив? – mpen

+2

@Mark Фактически я имею в виду «внешнюю» структуру данных. Ему нужен массив объектов. См. Мой пост ниже. –

0

Я подозреваю, что вам нужен массив вместо объекта. Поэтому вы должны изменить emails = {} на emails = [].

Если вы, как @PSL предложил вам закончить с таким объектом (который не является массивом):

{ 
    0: { 
    name: 'john' 
    email: '[email protected]' 
    }, 
    1: { 
    name: 'lennon' 
    email: '[email protected]' 
    } 
} 

Одно из возможных решений:

var contact, name, email, entry, 
    emails = []; 

for (var i = 0; i < contacts.length; i++) { 
    contact = contacts[i]; 
    emails.push({name: contact.fullName(), email: contact.selectedEmail()}); 
} 

Вы будете в конечном итоге с этим:

[ 
    { 
    name: 'john' 
    email: '[email protected]' 
    } 
    ,{ 
    name: 'lennon' 
    email: '[email protected]' 
    } 
] 
+1

Вы забыли полуточку, плохое качество копии ;-) – Virus721

+0

Я не копировал ваше сообщение - и точка с запятой не нужна кстати :) –

+0

@MarlonBernardes, помещающий полуколонну, является хорошей практикой. – PSL