53 lines
1.4 KiB
JavaScript
53 lines
1.4 KiB
JavaScript
/**
|
|
* When you have two-way bindings, but the actual bound value will not equal
|
|
* the value you initially passed in, then to avoid an infinite loop you
|
|
* need to increment a counter every time you pass in a value, decrement the
|
|
* same counter every time the bound value changed, but only bubble up
|
|
* the event when the counter is zero.
|
|
*
|
|
Example:
|
|
|
|
Let's say DrawingRecognitionCanvas is a deep-learning backed canvas
|
|
that, when given the name of an object (e.g. 'dog'), draws a dog.
|
|
But whenever the drawing on it changes, it also sends back its interpretation
|
|
of the image by way of the @newObjectRecognized event.
|
|
|
|
<input
|
|
type="text"
|
|
placeholder="an object, e.g. Dog, Cat, Frog"
|
|
v-model="identifiedObject" />
|
|
<DrawingRecognitionCanvas
|
|
:object="identifiedObject"
|
|
@newObjectRecognized="identifiedObject = $event"
|
|
/>
|
|
|
|
new TwoWayBindingWrapper((increment, decrement, shouldUpdate) => {
|
|
this.$watch('identifiedObject', () => {
|
|
// new object passed in
|
|
increment()
|
|
})
|
|
this.$deepLearningBackend.on('drawingChanged', () => {
|
|
recognizeObject(this.$deepLearningBackend)
|
|
.then((object) => {
|
|
decrement()
|
|
if (shouldUpdate()) {
|
|
this.$emit('newObjectRecognized', object.name)
|
|
}
|
|
})
|
|
})
|
|
})
|
|
*/
|
|
export default function TwoWayBindingWrapper(fn) {
|
|
let counter = 0
|
|
|
|
fn(
|
|
() => {
|
|
counter += 1
|
|
},
|
|
() => {
|
|
counter = Math.max(0, counter - 1)
|
|
},
|
|
() => counter === 0
|
|
)
|
|
}
|