44 lines
1.4 KiB
JavaScript
44 lines
1.4 KiB
JavaScript
function getTrackableObject(obj, callback) {
|
|
if (obj[Symbol.for('isTracked')]) return obj;
|
|
const tracked = Array.isArray(obj) ? [] : {};
|
|
for (const key in obj) {
|
|
Object.defineProperty(tracked, key, {
|
|
configurable: true,
|
|
enumerable: true,
|
|
get() {
|
|
return obj[key];
|
|
},
|
|
set(value) {
|
|
if (typeof value === 'object') {
|
|
value = getTrackableObject(value);
|
|
}
|
|
obj[key] = value;
|
|
callback(obj);
|
|
console.log(`'${key}' has changed. ` + obj[key]);
|
|
},
|
|
});
|
|
}
|
|
// marked as 'tracked'
|
|
Object.defineProperty(tracked, Symbol.for('isTracked'), {
|
|
configurable: false,
|
|
enumerable: false,
|
|
value: true,
|
|
});
|
|
return tracked;
|
|
}
|
|
|
|
const countElm = document.getElementById('count')
|
|
countElm.textContent = 0
|
|
// track app state
|
|
const appState = getTrackableObject({ count: 0 }, (obj) => countElm.textContent = obj.count);
|
|
// appState.count = appState.count + 1; // log `'foo' has changed.`
|
|
|
|
document.getElementById('btn-subtract').addEventListener('click', () => {
|
|
appState.count--;
|
|
})
|
|
document.getElementById('btn-reset').addEventListener('click', () => {
|
|
appState.count = 0;
|
|
})
|
|
document.getElementById('btn-add').addEventListener('click', () => {
|
|
appState.count++;
|
|
}) |