2010-11-12 3 views
9

Je dois déclencher un événement chaque fois qu'une propriété est mise à jour/modifiée afin de garder les éléments dom en synchronisation avec les valeurs de propriété du modèle (Im en utilisant l'héritage simple de john resig http://ejohn.org/blog/simple-javascript-inheritance/). Est-ce possible de le faire de manière croisée? Il me semble que si je pouvais envelopper n'importe quelle fonction que js utilise pour définir les propriétés et le faire déclencher un événement, cela pourrait fonctionner, je ne suis pas sûr de savoir comment faire cela.javascript événement de changement de propriété

Répondre

9

JavaScript n'utilise pas de fonction pour définir les propriétés. Ce ne sont que des variables, et leur définition ne nécessite pas d'enveloppes élaborées.

Vous pouvez utiliser une fonction pour définir la propriété, bien que - le même genre d'un arrangement getter/setter vous pouvez utiliser dans une langue qui a soutenu les données privées dans les classes. De cette façon, votre fonction pourrait facilement exécuter d'autres fonctions qui ont été enregistrées comme callbacks. En utilisant jQuery, vous pouvez même gérer ces événements.

$(yourObject).bind('some-event-you-made-up', function() { 
    // This code will run whenever some-event-you-made-up is triggered on yourObject 
}); 

// ... 

$(yourObject).trigger('some-event-you-made-up'); 
+3

Il est en fait possible d'avoir « getter » et les fonctions « setter » pour les propriétés de l'objet dans la Javascript étendu de Mozilla. – Pointy

+4

Ou dans ECMAScript 5. – casablanca

+0

Le problème est que l'objet que je veux écouter pour l'événement n'est pas un objet jquery, juste un objet générique qui est stocké dans l'objet de données jquery objects. Je ne sais pas comment lier un événement à cela. – joshontheweb

3

Peut-être que vous avez déjà résolu votre problème avec jQuery bind/déclencheur, mais je voulais dire que je suis la construction d'un suivi du changement et (en haut de cette) Entité de modélisation Javascript Framework, nommé « tente » qui permet de résoudre le problème que vous exposez, sans nécessiter aucune syntaxe spéciale sur la manipulation d'objets, son open source et hébergé chez:

https://github.com/benjamine/tent

Il est documenté avec JSDoc et l'unité testée avec js test-pilote.

vous pouvez utiliser le module de suivi des modifications de cette façon:

var myobject = { name: 'john', age: 34 }; 

    // add a change handler that shows changes on alert dialogs 
    tent.changes.bind(myobject, function(change) { 
     alert('myobject property '+change.data.propertyName+' changed!'); 
    }); 

    myobject.name = 'charly'; // gets notified on an alert dialog 

il fonctionne avec tableau change aussi (ajoute, supprime). En outre, vous pouvez utiliser les contextes "Entity" pour conserver les modifications de tous les changements détectés (ADDED, DELETED, MODIFIED items) groupés sur les collections, ajouter et supprimer en cascade, garder les propriétés inversées synchronisées, track 1-to-1, 1-to-1 N et relations N-à-M, etc.

+0

c'est un cadre très intéressant. –

0

Vous pouvez essayer Javascript Property Events (jpe.js)

j'ai rencontré un problème similaire, et a fini par écrire une fonction de surcharge pour Object.defineProperty qui ajoute des gestionnaires d'événements aux propriétés. Il fournit également une vérification de type (js-base-types) et stocke sa valeur en interne, empêchant ainsi les modifications indésirables.

Exemple de DefineProperty normal:

Object.defineProperty(document, "property", { 
    get:function(){return myProperty}, 
    set:function(value){myProperty = value}, 
}) 
var myProperty = false; 

Exemple de propriété avec onchange événement:

Object.defineProperty(document, "property", { 
    default:false, 
    get:function(){}, 
    set:function(value){}, 
    onchange:function(event){console.info(event)} 
}) 
+0

J'ai été choqué de voir un événement "onchange" là-bas, mais seulement plus tard je l'ai vu est un cadre haha –

0

objet DefineProperty/DefineProperties fait l'affaire. Ici va un code simple. J'ai construit des données cadres de liaison sur cette base, et il peut être vraiment complexe, mais pour l'exercice de son comme celui-ci:

var oScope = { 
    $privateScope:{}, 
    notify:function(sPropertyPath){ 
     console.log(sPropertyPath,"changed"); 
    } 
}; 
Object.defineProperties(oScope,{ 
    myPropertyA:{ 
     get:function(){ 
      return oScope.$privateScope.myPropertyA 
     }, 
     set:function(oValue){ 
      oScope.$privateScope.myPropertyA = oValue; 
      oScope.notify("myPropertyA"); 
     } 
    } 
}); 

oScope.myPropertyA = "Some Value"; 
//console will log: myPropertyA changed 
Questions connexes