الرجوع الي الدرس

Observable

قم بإنشاء الدالة makeObservable(target) والتي تقوم بجعل الأوبجكت observable عن طريق إرجاع بروكسي.

هنا كيف تعمل:

function makeObservable(target) {
  /* your code */
}

let user = {};
user = makeObservable(user);

user.observe((key, value) => {
  alert(`SET ${key}=${value}`);
});

user.name = "John"; // alerts: SET name=John

بعبارات أخري، الأوبجكت الذي يتم استرجاعه بواسطة makeObservable هو مثل الأوبجكت الأصلي ولكن يحتوي أيضًا علي الدالة observe(handler) والتي تنشئ handler يتم استدعاؤه في كل تغير لخاصية.

عند تغير أي خاصية، يتم استدعاء handler(key, value) بإسم وقيمة الخاصية.

ملاحظه: في هذا التكليف، اهتم فقط بعملية التعديل علي الخاصية. العمليات الأخري يمكن تطبيقها بنفس الطريقة.

يتكون الحل من جزئين:

  1. عند استدعاء .observe(handler) في أى وقت، نحتاج إلي أن نتذكر الـ handler فس أي مكان، لنكون قادرين علي استدعاءه لاحقًا. يمكن تخزين الـhandler في الأوبجكت باستخدام الرمز كاسم للخاصية.
  2. نحتاج إلي بروكسي يحتوي علي الtrap set لاستدعاء الhandlers في حالة التغيير.
let handlers = Symbol('handlers');

function makeObservable(target) {
  // 1. Initialize handlers store
  target[handlers] = [];

  // Store the handler function in array for future calls
  target.observe = function(handler) {
    this[handlers].push(handler);
  };

  // 2. Create a proxy to handle changes
  return new Proxy(target, {
    set(target, property, value, receiver) {
      let success = Reflect.set(...arguments); // forward the operation to object
      if (success) { // if there were no error while setting the property
        // call all handlers
        target[handlers].forEach(handler => handler(property, value));
      }
      return success;
    }
  });
}

let user = {};

user = makeObservable(user);

user.observe((key, value) => {
  alert(`SET ${key}=${value}`);
});

user.name = "John";