2009-02-22 11 views
2

j'ai cet objet:tableaux Associatif en javascript

function formBuddy() 
{ 
    var fields = new Array(); 
    var labels = new Array(); 
    var rules = new Array(); 
    var count=0; 

    this.addField = function(field, label, rule) 
    { 
     fields[count] = field; 
     labels[field] = label; 
     rules[field] = rule; 
     count = ++count; 
    } 
} 

Son utilisés de cette manière:

var cForm=new formBuddy(); 
cForm.addField("c_first_name","First Name","required"); 
cForm.addField("c_last_name","Last Name","required"); 

Le problème est, dans la fonction addField() le tableau fields est réglée correctement (peut-être parce que un index numérique est utilisé pour s'y référer) mais les deux autres tableaux (labels et rules) ne sont pas touchés du tout. Faire un console.log les montre comme vides dans firebug.

Que dois-je changer pour les faire fonctionner? Je voudrais toujours me référer aux règles et aux étiquettes par l'index de la chaîne du champ.

+0

Javascript ne pas les tableaux associatifs natifs, seuls les objets. Les objets ont des propriétés et le nom de la propriété est toujours une chaîne. Même l'index des tableaux est converti en une chaîne avant que la 'magie du tableau' arrive. – some

Répondre

8

Utilisez les objets à la place:

function formBuddy() 
{ 
    var fields = {}; 
    var labels = {}; 
    var rules = {}; 
    var count = 0; 

    this.addField = function(field, label, rule) 
    { 
     fields[count] = field; 
     labels[field] = label; 
     rules[field] = rule; 
     count++; 
    } 
} 

Mais comme Christoph already mentioned, je stockerait ces informations dans une seule structure de données aussi. Par exemple:

function formBuddy() { 
    var fields = {}; 
    this.addField = function(name, label, rule) { 
     fields[name] = { 
      name: name, 
      label: label, 
      rule: rule 
     }; 
    }; 
    this.getField = function(name) { 
     return fields[name]; 
    }; 
} 

var cForm=new formBuddy(); 
cForm.addField("c_first_name","First Name","required"); 
cForm.addField("c_last_name","Last Name","required"); 
alert(cForm.getField("c_last_name").label); 
+0

En effet, javascript n'a pas de tableaux associatifs.Un tableau associatif est un objet. –

+0

Si je fais des règles [champ] alors (où champ est une chaîne contenant un nom de champ) cela fonctionnerait-il? –

+0

Pourquoi utiliser les objets lorsque vous pouvez simplement augmenter les tableaux? -1. –

0

Les tableaux sont traités comme des objets Javascript, donc votre morceau de code fonctionne, il est juste que console.log de Firebug pas vous montrer les « objets » à l'intérieur du tableau, plutôt seulement les valeurs du tableau .. .

utilisez le for(var i in obj) pour voir quels objets les valeurs du tableau contient:

function formBuddy() { 
    var fields = new Array(); 
    var labels = new Array(); 
    var rules = new Array(); 
    var count=0; 

    this.addField = function(field, label, rule) 
    {   
     fields[count] = field; 
     labels[field] = label; 
     rules[field] = rule; 
     count = ++count; 

     for(var i in labels) { 
      console.log(labels[i]); 
     } 
     for(var i in rules) { 
      console.log(rules[i]); 
     } 

     console.log(labels.c_last_name); 
     // or 
     console.log(labels["c_last_name"]); 
    } 
} 

var cForm = new formBuddy(); 
cForm.addField("c_last_name","Last Name","required"); 
+0

Ce que je dois faire est de pouvoir récupérer la règle d'un champ. E.g rule = rules [field], ou rule = rules.field. Cela ne fonctionne pas actuellement avec le code de tableaux et me donne une erreur. –

+0

Fonctionne pour moi console.log (labels ["c_last_name"]); ou console.log (labels.c_last_name); –

+0

vous devriez vérifier 'hasOwnProperty()' lors de la boucle sur les propriétés - il y a quelque temps, il était à la mode d'étendre 'Array.prototype' – Christoph

2

fields doit être un tableau, alors que labels et rules doivent être des objets que vous souhaitez utiliser cordes comme clés. En outre, addField() est le même pour chaque instance de FormBuddy() (noms des fonctions constructeur doivent être capitalisées) et doivent résider dans le prototype, à savoir

function FormBuddy() { 
    this.fields = []; // this is the same as `new Array()` 
    this.labels = {}; // this is the same as `new Object()` 
    this.rules = {}; 
} 

FormBuddy.prototype.addField = function(field, label, rule) { 
    this.fields.push(field); 
    this.labels[field] = label; 
    this.rules[field] = rule; 
}; 

Vous pouvez accéder aux étiquettes/règles via

var buddy = new FormBuddy(); 
buddy.addField('foo', 'bar', 'baz'); 
alert(buddy.labels['foo']); 
alert(buddy.rules.foo); 

Juste pour Enragé encore Luca;), voici une autre version qui dosn't aussi tout résumer:

function FormBuddy() { 
    this.fields = []; 
} 

FormBuddy.prototype.addField = function(id, label, rule) { 
    var field = { 
     id : id, 
     label : label, 
     rule : rule 
    }; 

    this.fields.push(field); 
    this['field ' + id] = field; 
}; 

FormBuddy.prototype.getField = function(id) { 
    return this['field ' + id]; 
}; 

var buddy = new FormBuddy(); 
buddy.addField('foo', 'label for foo', 'rule for foo'); 

Il est similaire à la deuxième version de Gumbo, mais son objet fields est fusionné dans l'instance FormBuddy. Un tableau appelé fields est ajouté à la place pour permettre une itération rapide.

Pour accéder à une étiquette de champ, une règle ou id, utilisez

buddy.getField('foo').label 

Pour parcourir les champs, utilisez

// list rules: 
for(var i = 0, len = buddy.fields.length; i < len; ++i) 
    document.writeln(buddy.fields[i].rule); 
+0

Vous avez perdu le prototype? –

+0

@Luca: Oui - je l'ai corrigé;) – Christoph

+0

Je pense qu'il/elle veut que les propriétés soient privées, je pourrais me tromper. –

Questions connexes