Object.watch () cho tất cả các trình duyệt?


118

Xin lưu ý rằng Object.WatchObject.Observeđều bị phản đối tại (tính đến tháng 6 năm 2018).


Tôi đang tìm kiếm một cách dễ dàng để theo dõi một đối tượng hoặc biến để thay đổi và tôi nhận thấy Object.watch(), cách này được hỗ trợ trong trình duyệt Mozilla, nhưng không hỗ trợ IE. Vì vậy, tôi bắt đầu tìm kiếm xung quanh để xem có ai đã viết một số loại tương đương.

Về thứ duy nhất tôi tìm thấy là một plugin jQuery , nhưng tôi không chắc đó có phải là cách tốt nhất để sử dụng hay không. Tôi chắc chắn sử dụng jQuery trong hầu hết các dự án của mình, vì vậy tôi không lo lắng về khía cạnh jQuery ...

Dù sao, câu hỏi: Ai đó có thể chỉ cho tôi một ví dụ hoạt động của plugin jQuery đó không? Tôi đang gặp sự cố làm cho nó hoạt động ...

Hoặc, có ai biết về bất kỳ lựa chọn thay thế nào tốt hơn có thể hoạt động trên nhiều trình duyệt không?

Cập nhật sau câu trả lời :

Cảm ơn mọi người cho hồi đáp! Tôi đã thử mã được đăng ở đây: http://webreflection.blogspot.com/2009/01/internet-explorer-object-watch.html

Nhưng tôi dường như không thể làm cho nó hoạt động với IE. Đoạn mã dưới đây hoạt động tốt trên Firefox, nhưng không hoạt động trong IE. Trong Firefox, mỗi lần watcher.statusđược thay đổi, document.write()trong watcher.watch()được gọi và bạn sẽ nhìn thấy đầu ra trên trang. Trong IE, điều đó không xảy ra, nhưng tôi có thể thấy điều đó watcher.statusđang cập nhật giá trị, vì lệnh document.write()gọi cuối cùng hiển thị giá trị chính xác (trong cả IE và FF). Nhưng, nếu hàm gọi lại không được gọi, thì điều đó thật vô nghĩa ... :)

Tui bỏ lỡ điều gì vậy?

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 bạn có thể sử dụng onPropertyChange trong IE
scunliffe

1
Thay thế document.write () bằng alert (). Nó sẽ hoạt động tốt.
Ionuț G. Stan

Câu trả lời:


113

(Xin lỗi vì đã đăng chéo, nhưng câu trả lời này tôi đã đưa ra cho một câu hỏi tương tự hoạt động tốt ở đây)

Tôi đã tạo một vật thể nhỏ. Đồng hồ chêm cho cái này một lúc trước. Nó hoạt động trên IE8, Safari, Chrome, Firefox, Opera, v.v.


10
Lời giải thích về cách sử dụng nó và cách hoạt động nội bộ của nó sẽ rất hay cho những người trong chúng ta không phải là người thành thạo JS, cảm ơn.
maraujop


jsfiddle.net/kSWxP GỢI Ý: sử dụng Firefox (báo cáo kết quả sau này không được in trong Chrome)
Mars Robertson


Tôi đã biết ý tưởng Object.defineProperty()tồn tại. Tôi đã kết thúc việc xem tài liệu tham khảo MDN để xem nó hoạt động như thế nào.
jumpnett

19

Plugin đó chỉ đơn giản là sử dụng bộ đếm thời gian / khoảng thời gian để liên tục kiểm tra các thay đổi trên một đối tượng. Có thể đủ tốt nhưng cá nhân tôi muốn quan sát nhanh hơn.

Đây là nỗ lực đưa watch/ unwatchđến IE: http://webreflection.blogspot.com/2009/01/internet-explorer-object-watch.html .

Nó thay đổi cú pháp từ cách thêm người quan sát của Firefox. Thay vì :

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

Bạn làm:

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

Không ngọt ngào bằng, nhưng là một người quan sát, bạn sẽ được thông báo ngay lập tức.


Đúng, hãy xem những dấu thời gian đó ... không cần phải phản đối, crescentfresh cũng đã thêm nhiều thông tin hơn vào bài đăng, ngay cả khi đó là cùng một liên kết. Trong khi đó, tôi đã thử mã được tìm thấy trên trang đó và vẫn gặp sự cố. Tôi có thể đang xem xét một cái gì đó mặc dù. Tôi đã cập nhật bài đăng gốc của mình với nhiều thông tin hơn ...
SeanW

13

Các câu trả lời cho câu hỏi này đã hơi lỗi thời. Object.watchObject.observe đều không được dùng nữa và không nên sử dụng.

Ngày nay, bạn có thể sử dụng đối tượng Proxy để theo dõi (và chặn) các thay đổi được thực hiện đối với một đối tượng. Đây là một ví dụ cơ bản:

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'

Nếu bạn cần quan sát những thay đổi được thực hiện đối với một đối tượng lồng nhau, thì bạn cần sử dụng một thư viện chuyên biệt. Tôi đã xuất bản Observable Slim và nó hoạt động như thế này:

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

Câu trả lời hiện tại

Sử dụng đối tượng Proxy mới , đối tượng này có thể theo dõi các thay đổi đối với mục tiêu của 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

Câu trả lời cũ từ năm 2015

Bạn có thể đã sử dụng Object.observe () từ ES7 . Đây là một polyfill. Nhưng Object.observe () hiện đã bị hủy . Xin lỗi mọi người!


Rất tiếc, tôi không thể làm cho polyfill này hoạt động trên ios safari. Tôi gặp lỗi: undefined không phải là một hàm (đánh giá 'Object.observe (a.imgTouch, function (a) {console.debug ("lastX:" + a)})')
infomofo

@infomofo Xin chào, bạn có muốn mở một vấn đề trên trang của dự án với tất cả các chi tiết bạn có thể cung cấp không? Tôi chưa thử nghiệm nó trên iOS, nhưng tôi sẽ xem xét vấn đề.
MaxArt

6

Lưu ý rằng trong Chrome 36 trở lên, bạn cũng có thể sử dụng Object.observe. Đây thực sự là một phần của tiêu chuẩn ECMAScript trong tương lai, và không phải là một tính năng dành riêng cho trình duyệt như của Mozilla Object.watch.

Object.observechỉ hoạt động trên các thuộc tính đối tượng, nhưng hoạt động hiệu quả hơn rất nhiều so với Object.watch(nghĩa là cho mục đích gỡ lỗi, không phải sử dụng sản xuất).

var options = {};

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

options.foo = 'bar';

1
Kể từ năm 2018, tính năng này không được dùng nữa và không còn được hỗ trợ bởi tất cả các trình duyệt chính nữa
Sergei Panfilov

4

bạn có thể sử dụng Object.defineProperty .

xem tài sản barfoo

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

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

Điều đó thật tuyệt! Nhưng tôi sẽ sửa đổi nó. :) Để không ghi đè setter ban đầu. Tôi sẽ làm tài liệu tham khảo foo._someObject = foo.someObject
calmbird

đơn giản và thanh lịch
ßãlãjî

1

Tôi đã sử dụng Watch.js trong một trong những dự án của mình. Và nó đang hoạt động tốt. Một trong những lợi thế chính của việc sử dụng thư viện này là:

"Với Watch.JS bạn sẽ không phải thay đổi cách phát triển của mình."

Ví dụ được đưa ra dưới đây

//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>

Điều này là đơn giản như thế này!


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.