Veuillez noter que Object.Watch
et Object.Observe
sont désormais obsolètes (à partir de juin 2018).
Je cherchais un moyen simple de surveiller les modifications apportées à un objet ou à une variable, et j’ai trouvé Object.watch()
, qui est pris en charge par les navigateurs Mozilla, mais pas par IE. Alors j'ai commencé à chercher pour voir si quelqu'un avait écrit une sorte d'équivalent.
À propos de la seule chose que j'ai trouvée a été n plugin jQuery , mais je ne suis pas sûr que ce soit la meilleure façon de faire. J'utilise certainement jQuery dans la plupart de mes projets, je ne m'inquiète donc pas pour l'aspect jQuery ...
Quoi qu'il en soit, la question: quelqu'un peut-il me montrer un exemple de travail de ce plugin jQuery? J'ai du mal à le faire fonctionner ...
Ou, est-ce que quelqu'un connaît de meilleures alternatives qui fonctionneraient avec plusieurs navigateurs?
Mise à jour après les réponses :
Merci à tous pour les réponses! J'ai essayé le code posté ici: http://webreflection.blogspot.com/2009/01/internet-Explorer-object-watch.html
Mais je n'arrivais pas à le faire fonctionner avec IE. Le code ci-dessous fonctionne bien dans Firefox, mais ne fait rien dans IE. Dans Firefox, chaque fois que watcher.status
Est modifié, la document.write()
dans watcher.watch()
est appelée et vous pouvez voir la sortie sur la page. Cela ne se produit pas dans IE, mais je peux voir que watcher.status
Met à jour la valeur, car le dernier appel de document.write()
indique la valeur correcte (dans les deux IE et FF). Mais si la fonction de rappel n’est pas appelée, c’est inutile, alors ... :)
Est-ce que je manque quelque chose?
var options = {'status': 'no status'},
watcher = createWatcher(options);
watcher.watch("status", function(prop, oldValue, newValue) {
document.write("old: " + oldValue + ", new: " + newValue + "<br>");
return newValue;
});
watcher.status = 'asdf';
watcher.status = '1234';
document.write(watcher.status + "<br>");
(Désolé pour le commentaire croisé, mais cette réponse que j'ai donnée à une question similaire fonctionne bien ici)
J'ai créé un petit object.watch shim pour cela il y a quelque temps. Cela fonctionne dans IE8, Safari, Chrome, Firefox, Opera, etc.
Ce plugin utilise simplement un minuteur/intervalle pour vérifier de manière répétée les modifications apportées à un objet. Peut-être assez bon mais personnellement, je voudrais plus d’immédiateté en tant qu’observateur.
Voici une tentative pour amener watch
/unwatch
à IE: http://webreflection.blogspot.com/2009/01/internet-Explorer-object-watch.html =.
Cela modifie la syntaxe par rapport à la façon dont Firefox ajoute des observateurs. Au lieu de :
var obj = {foo:'bar'};
obj.watch('foo', fooChanged);
Tu fais:
var obj = {foo:'bar'};
var watcher = createWatcher(obj);
watcher.watch('foo', fooChanged);
Pas aussi gentil, mais en tant qu'observateur, vous êtes immédiatement averti.
Les réponses à cette question sont un peu dépassées. Object.watch et Object.observe sont tous deux obsolètes et ne doivent pas être utilisés.
Aujourd'hui, vous pouvez maintenant utiliser l'objet Proxy pour surveiller (et intercepter) les modifications apportées à un objet. Voici un exemple de base:
var targetObj = {};
var targetProxy = new Proxy(targetObj, {
set: function (target, key, value) {
console.log(`${key} set to ${value}`);
target[key] = value;
}
});
targetProxy.hello_world = "test"; // console: 'hello_world set to test'
Si vous devez observer les modifications apportées à un objet imbriqué, vous devez utiliser une bibliothèque spécialisée. J'ai publié Observable Slim et cela fonctionne comme ceci:
var test = {testing:{}};
var p = ObservableSlim.create(test, true, function(changes) {
console.log(JSON.stringify(changes));
});
p.testing.blah = 42; // console: [{"type":"add","target":{"blah":42},"property":"blah","newValue":42,"currentPath":"testing.blah",jsonPointer:"/testing/blah","proxy":{"blah":42}}]
Réponse actuelle
Utilisez le nouvel objet Proxy , qui peut suivre les modifications apportées à sa cible.
let validator = {
set: function(obj, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('The age is not an integer');
}
if (value > 200) {
throw new RangeError('The age seems invalid');
}
}
// The default behavior to store the value
obj[prop] = value;
// Indicate success
return true;
}
};
let person = new Proxy({}, validator);
person.age = 100;
console.log(person.age); // 100
person.age = 'young'; // Throws an exception
person.age = 300; // Throws an exception
Ancienne réponse de 2015
Vous auriez pu utiliser Object.observe () de ES7 . Voici un polyfill. Mais Object.observe () est maintenant annulé . Désolé les gens!
Notez que dans Chrome 36 et supérieur, vous pouvez également utiliser Object.observe
. Il s’agit en fait d’une partie d’un futur standard ECMAScript et non d’un navigateur. fonction spécifique comme le Object.watch
de Mozilla.
Object.observe
Ne fonctionne que sur les propriétés des objets, mais est beaucoup plus performant que Object.watch
(Destiné à des fins de débogage et non à une utilisation en production).
var options = {};
Object.observe(options, function(changes) {
console.log(changes);
});
options.foo = 'bar';
vous pouvez utiliser Object.defineProperty .
regarder la propriété bar
dans foo
Object.defineProperty(foo, "bar", {
get: function (val){
//some code to watch the getter function
},
set: function (val) {
//some code to watch the setter function
}
})
J'ai utilisé Watch.js dans l'un de mes projets. Et cela fonctionne très bien. L’un des principaux avantages de l’utilisation de cette bibliothèque est:
"Avec Watch.JS, vous n’aurez pas à changer votre façon de vous développer."
L'exemple est donné ci-dessous
//defining our object however we like
var ex1 = {
attr1: "initial value of attr1",
attr2: "initial value of attr2"
};
//defining a 'watcher' for an attribute
watch(ex1, "attr1", function(){
alert("attr1 changed!");
});
//when changing the attribute its watcher will be invoked
ex1.attr1 = "other value";
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src/watch.min.js"></script>
C'est aussi simple que ça!