Tüm tarayıcılar için Object.watch ()?


118

Unutmayın ki Object.Watchve Object.Observeher ikisi (Jun 2018 itibariyle) şimdi artık yok.


Değişiklikler için bir nesneyi veya değişkeni izlemenin kolay bir yolunu arıyordum ve bunun Object.watch()Mozilla tarayıcılarında desteklendiğini ancak IE'de desteklenmediğini buldum . Bu yüzden, birinin eşdeğer bir tür yazıp yazmadığını görmek için etrafı araştırmaya başladım.

Bulduğum tek şey bir jQuery eklentisi oldu , ancak bunun en iyi yol olup olmadığından emin değilim. Projelerimin çoğunda kesinlikle jQuery kullanıyorum, bu yüzden jQuery yönü hakkında endişelenmiyorum ...

Her neyse, soru şu: Biri bana o jQuery eklentisinin çalışan bir örneğini gösterebilir mi? Çalışmasını sağlamakta sorunlar yaşıyorum ...

Veya, çapraz tarayıcıda çalışacak daha iyi alternatifler bilen var mı?

Cevaplardan sonra güncelleme :

Yanıtlar için herkese teşekkürler! Burada yayınlanan kodu denedim: http://webreflection.blogspot.com/2009/01/internet-explorer-object-watch.html

Ama IE ile çalışmasını sağlayamadım. Aşağıdaki kod Firefox'ta iyi çalışıyor, ancak IE'de hiçbir şey yapmıyor. Firefox'ta her watcher.statusdeğiştirildiğinde, document.write()in watcher.watch()çağrılır ve çıktıyı sayfada görebilirsiniz. IE'de bu olmaz, ancak bunun watcher.statusdeğeri güncellediğini görebiliyorum , çünkü son document.write()çağrı doğru değeri gösteriyor (hem IE hem de FF'de). Ancak, geri arama işlevi çağrılmazsa, bu biraz anlamsız ... :)

Bir şey mi kaçırıyorum?

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>");

2
IIRC, IE'de
Mülk Değişiminde

1
Document.write () öğesini alert () ile değiştirin. İyi çalışmalı.
Ionuț G. Stan

Yanıtlar:


113

(Çapraz gönderi için üzgünüm ama benzer bir soruya verdiğim bu cevap burada iyi çalışıyor)

Küçük bir obje oluşturdum . Bunun için bir süre önce şim izle . IE8, Safari, Chrome, Firefox, Opera vb. İle çalışır.


10
Nasıl kullanılacağına ve dahili olarak nasıl çalıştığına dair bir açıklama JS ustası olmayan bizler için güzel olurdu, teşekkürler.
maraujop


jsfiddle.net/kSWxP İPUCU: Firefox kullanın (ikinci ifade Chrome'da yazdırılmamaktadır)
Mars Robertson


Bir fikrin Object.defineProperty()var olduğunu biliyordum. Nasıl çalıştığını görmek için MDN referansına baktım .
jumpnett

19

Bu eklenti, bir nesnedeki değişiklikleri tekrar tekrar kontrol etmek için bir zamanlayıcı / aralık kullanır. Belki yeterince iyi ama şahsen bir gözlemci olarak daha yakın olmak isterim.

İşte IE'ye watch/ getirme girişimi unwatch: http://webreflection.blogspot.com/2009/01/internet-explorer-object-watch.html .

Sözdizimini Firefox gözlemci ekleme yönteminden değiştirir. Onun yerine :

var obj = {foo:'bar'};
obj.watch('foo', fooChanged);

Siz yapıyorsunuz:

var obj = {foo:'bar'};
var watcher = createWatcher(obj);
watcher.watch('foo', fooChanged);

O kadar tatlı değil, ama bir gözlemci olarak hemen bilgilendiriliyorsunuz.


Evet, bu zaman damgalarını izleyin ... olumsuz oy kullanmanıza gerek yok, ayrıca hilal aynı bağlantı olsa bile gönderiye daha fazla bilgi ekledi. Bu arada, o sayfada bulunan kodu denedim ve hala bir sorun görüyorum. Yine de bir şeyi gözden kaçırıyor olabilirim. Orijinal gönderimi daha fazla bilgi ile güncelledim ...
SeanW

13

Bu sorunun cevapları biraz modası geçmiş. Object.watch ve Object.observe kullanımdan kaldırılmıştır ve kullanılmamalıdır.

Bugün, bir nesnede yapılan değişiklikleri izlemek (ve engellemek) için artık Proxy nesnesini kullanabilirsiniz . İşte temel bir örnek:

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'

İç içe geçmiş bir nesnede yapılan değişiklikleri gözlemlemeniz gerekiyorsa, özel bir kitaplık kullanmanız gerekir. Observable Slim'i yayınladım ve şu şekilde çalışıyor:

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}}]

12

Mevcut Cevap

Hedefindeki değişiklikleri izleyebilen yeni Proxy nesnesini kullanın .

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

2015'ten eski cevap

Sen kullanılan olabilir ES7 dan Object.observe () . İşte bir polyfill. Ancak Object.observe () artık iptal edildi . Üzgünüm millet!


Hm, bu çoklu dolguyu ios safaride çalıştıramadım. Hata alıyorum: undefined bir işlev değil ('Object.observe (a.imgTouch, function (a) {console.debug ("lastX:" + a)})' değerlendiriliyor)
infomofo

@infomofo Merhaba, proje sayfasında verebileceğiniz tüm detayları içeren bir sayı açmak ister misiniz? İOS'ta test etmedim, ancak sorunu inceleyeceğim.
MaxArt

6

Chrome 36 ve sonraki sürümlerde de kullanabileceğinizi unutmayın Object.observe. Bu aslında gelecekteki ECMAScript standardının bir parçasıdır ve Mozilla'nınki gibi tarayıcıya özgü bir özellik değildir Object.watch.

Object.observeyalnızca nesne özelliklerinde çalışır, ancak Object.watch(bu, üretim kullanımı için değil, hata ayıklama amaçlıdır) olandan çok daha fazla performans gösterir .

var options = {};

Object.observe(options, function(changes) {
    console.log(changes);
});

options.foo = 'bar';

1
2018'de olduğu gibi, bu kullanımdan kaldırıldı ve artık tüm büyük tarayıcılar tarafından desteklenmiyor
Sergei Panfilov

4

Object.defineProperty'yi kullanabilirsiniz .

özelliği izlemek bariçindefoo

Object.defineProperty(foo, "bar", {
  get: function (val){
      //some code to watch the getter function
  },

  set: function (val) {
      //some code to watch the setter function
  }
})

Bu harika! Ama abit değiştirirdim :) Orijinal dizicinin üzerine yazmamak için. Referans foo._someObject = foo.someObject
sakinbird

basit ve zarafet
ßãlãjî

1

Projelerimden birinde Watch.js kullandım . Ve iyi çalışıyor. Bu kitaplığı kullanmanın temel avantajlarından biri:

"Watch.JS ile geliştirme şeklinizi değiştirmek zorunda kalmayacaksınız."

Örnek aşağıda verilmiştir

//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/melanke-watchjs@1.5.0/src/watch.min.js"></script>

Bu kadar basit!


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.