Skip to content

Commit

Permalink
Add $watch method
Browse files Browse the repository at this point in the history
  • Loading branch information
calebporzio committed Mar 16, 2020
1 parent df1bec9 commit 07d2cdc
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 5 deletions.
22 changes: 20 additions & 2 deletions dist/alpine-ie11.js
Original file line number Diff line number Diff line change
Expand Up @@ -6310,6 +6310,7 @@
this.unobservedData.$el = null;
this.unobservedData.$refs = null;
this.unobservedData.$nextTick = null;
this.unobservedData.$watch = null;
/* IE11-ONLY:END */
// Construct a Proxy-based observable. This will be used to handle reactivity.

Expand All @@ -6331,6 +6332,15 @@
this.nextTickStack.push(callback);
}.bind(this);

this.watchers = {};

this.unobservedData.$watch = function (property, callback) {
_newArrowCheck(this, _this);

if (!this.watchers[property]) this.watchers[property] = [];
this.watchers[property].push(callback);
}.bind(this);

this.showDirectiveStack = [];
this.showDirectiveLastElement;
var initReturnedCallback; // If x-init is present AND we aren't cloning (skip x-init on clone)
Expand Down Expand Up @@ -6366,7 +6376,7 @@
Object.keys(unwrappedData).forEach(function (key) {
_newArrowCheck(this, _this2);

if (['$el', '$refs', '$nextTick'].includes(key)) return;
if (['$el', '$refs', '$nextTick', '$watch'].includes(key)) return;
copy[key] = unwrappedData[key];
}.bind(this));
return copy;
Expand All @@ -6379,7 +6389,15 @@
valueMutated: function valueMutated(target, key) {
var _this3 = this;

// Don't react to data changes for cases like the `x-created` hook.
if (self.watchers[key]) {
self.watchers[key].forEach(function (callback) {
_newArrowCheck(this, _this3);

return callback(target[key]);
}.bind(this));
} // Don't react to data changes for cases like the `x-created` hook.


if (self.pauseReactivity) return;
debounce(function () {
_newArrowCheck(this, _this3);
Expand Down
15 changes: 13 additions & 2 deletions dist/alpine.js
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,13 @@
this.nextTickStack.push(callback);
};

this.watchers = {};

this.unobservedData.$watch = (property, callback) => {
if (!this.watchers[property]) this.watchers[property] = [];
this.watchers[property].push(callback);
};

this.showDirectiveStack = [];
this.showDirectiveLastElement;
var initReturnedCallback; // If x-init is present AND we aren't cloning (skip x-init on clone)
Expand Down Expand Up @@ -1272,7 +1279,7 @@
let unwrappedData = this.membrane.unwrapProxy(this.$data);
let copy = {};
Object.keys(unwrappedData).forEach(key => {
if (['$el', '$refs', '$nextTick'].includes(key)) return;
if (['$el', '$refs', '$nextTick', '$watch'].includes(key)) return;
copy[key] = unwrappedData[key];
});
return copy;
Expand All @@ -1282,7 +1289,11 @@
var self = this;
let membrane = new ReactiveMembrane({
valueMutated(target, key) {
// Don't react to data changes for cases like the `x-created` hook.
if (self.watchers[key]) {
self.watchers[key].forEach(callback => callback(target[key]));
} // Don't react to data changes for cases like the `x-created` hook.


if (self.pauseReactivity) return;
debounce(() => {
self.updateElements(self.$el); // Walk through the $nextTick stack and clear it as we go.
Expand Down
14 changes: 13 additions & 1 deletion src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export default class Component {
this.unobservedData.$el = null
this.unobservedData.$refs = null
this.unobservedData.$nextTick = null
this.unobservedData.$watch = null
/* IE11-ONLY:END */

// Construct a Proxy-based observable. This will be used to handle reactivity.
Expand All @@ -40,6 +41,13 @@ export default class Component {
this.nextTickStack.push(callback)
}

this.watchers = {}
this.unobservedData.$watch = (property, callback) => {
if (! this.watchers[property]) this.watchers[property] = []

this.watchers[property].push(callback)
}

this.showDirectiveStack = []
this.showDirectiveLastElement

Expand Down Expand Up @@ -72,7 +80,7 @@ export default class Component {
let copy = {}

Object.keys(unwrappedData).forEach(key => {
if (['$el', '$refs', '$nextTick'].includes(key)) return
if (['$el', '$refs', '$nextTick', '$watch'].includes(key)) return

copy[key] = unwrappedData[key]
})
Expand All @@ -85,6 +93,10 @@ export default class Component {

let membrane = new ObservableMembrane({
valueMutated(target, key) {
if (self.watchers[key]) {
self.watchers[key].forEach(callback => callback(target[key]))
}

// Don't react to data changes for cases like the `x-created` hook.
if (self.pauseReactivity) return

Expand Down
29 changes: 29 additions & 0 deletions test/watch.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Alpine from 'alpinejs'
import { wait } from '@testing-library/dom'

global.MutationObserver = class {
observe() {}
}

test('$watch', async () => {
document.body.innerHTML = `
<div x-data="{ foo: 'bar', bob: 'lob' }" x-init="$watch('foo', value => { bob = value })">
<h1 x-text="foo"></h1>
<h2 x-text="bob"></h2>
<button x-on:click="foo = 'baz'"></button>
</div>
`

Alpine.start()

expect(document.querySelector('h1').innerText).toEqual('bar')
expect(document.querySelector('h2').innerText).toEqual('lob')

document.querySelector('button').click()

await wait(() => {
expect(document.querySelector('h1').innerText).toEqual('baz')
expect(document.querySelector('h2').innerText).toEqual('baz')
})
})

0 comments on commit 07d2cdc

Please sign in to comment.