From e36a76312e8f4f48a67666ec4b07e25287127880 Mon Sep 17 00:00:00 2001 From: Anthony Johnston Date: Sun, 20 Jan 2019 01:01:36 +0000 Subject: [PATCH 1/2] fix: initial binding value where 'this' is the element --- src/bind.spec.ts | 16 +++++++++------- src/bind.ts | 5 ++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/bind.spec.ts b/src/bind.spec.ts index 20194a7..545b03d 100644 --- a/src/bind.spec.ts +++ b/src/bind.spec.ts @@ -32,22 +32,24 @@ describe('bind', () => { }); it('this is bound to element in getters', async () => { - document.documentElement.innerHTML = '
'; + document.documentElement.innerHTML = ` +
+
+ `; - const el = document.querySelector('[bind]'); - let elThis: HTMLElement; + const els = document.querySelectorAll('[bind]'); const context = { get html() { - elThis = this; - return 'inserted'; + return `inserted ${this.dataset.id}`; } }; bind(document, context); - expect(el.innerHTML).toEqual(context.html); - expect(elThis).toBe(el); + expect(els[0].innerHTML).toEqual('inserted one'); + expect(els[1].innerHTML).toEqual('inserted two'); + }); it('this is bound to element in event handlers', async () => { diff --git a/src/bind.ts b/src/bind.ts index 47fbcbf..7b1c5c6 100644 --- a/src/bind.ts +++ b/src/bind.ts @@ -33,10 +33,9 @@ export function bind(rootElement: Document | Element, context: any): void { } if (getValue() !== value) setValue(value); }, - get: getValue.bind(element) + get: getValue }); - component[binding.componentMemberName] = - context[binding.contextMemberName]; + component[binding.componentMemberName] = getValue.bind(element)(); }); //bind Events From 8e5c3965fe1d0a9dfd12f14c4b789c44f5a025ba Mon Sep 17 00:00:00 2001 From: Anthony Johnston Date: Sun, 20 Jan 2019 18:18:19 +0000 Subject: [PATCH 2/2] fix: replace getters with a function - simple api for updaing --- src/bind.spec.ts | 25 ++++++++++++++++++++----- src/bind.ts | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/bind.spec.ts b/src/bind.spec.ts index 545b03d..d504ced 100644 --- a/src/bind.spec.ts +++ b/src/bind.spec.ts @@ -2,7 +2,10 @@ import { bind } from './bind'; describe('bind', () => { it('binds attributes', () => { - document.documentElement.innerHTML = '
'; + document.documentElement.innerHTML = ` +
+
+ `; const context = { html: 'inserted' @@ -10,9 +13,16 @@ describe('bind', () => { bind(document, context); - const el = document.querySelector('[bind]'); + const els = document.querySelectorAll('[bind]'); - expect(el.innerHTML).toEqual(context.html); + expect(els[0].innerHTML).toEqual(context.html); + expect(els[1].innerHTML).toEqual(context.html); + + const update ='updated'; + context.html = update; + + expect(els[0].innerHTML).toEqual(update); + expect(els[1].innerHTML).toEqual(update); }); it('binds events', async () => { @@ -31,7 +41,7 @@ describe('bind', () => { expect(recievedEvent).not.toBeUndefined(); }); - it('this is bound to element in getters', async () => { + it('this is bound to element in function properties', async () => { document.documentElement.innerHTML = `
@@ -40,7 +50,7 @@ describe('bind', () => { const els = document.querySelectorAll('[bind]'); const context = { - get html() { + html() { return `inserted ${this.dataset.id}`; } }; @@ -50,6 +60,11 @@ describe('bind', () => { expect(els[0].innerHTML).toEqual('inserted one'); expect(els[1].innerHTML).toEqual('inserted two'); + els[0].dataset.id = 'three'; + context.html(); + + expect(els[0].innerHTML).toEqual('inserted three'); + expect(els[1].innerHTML).toEqual('inserted two'); }); it('this is bound to element in event handlers', async () => { diff --git a/src/bind.ts b/src/bind.ts index 7b1c5c6..cb69fd2 100644 --- a/src/bind.ts +++ b/src/bind.ts @@ -23,19 +23,39 @@ export function bind(rootElement: Document | Element, context: any): void { Object.getOwnPropertyDescriptor(context, binding.contextMemberName) || {}; - let setValue = descriptor.set || (value => (descriptor.value = value)); - let getValue = descriptor.get || (() => descriptor.value); + if (typeof descriptor.value === 'function') { + const fn = descriptor.value['fn'] || descriptor.value; - Object.defineProperty(context, binding.contextMemberName, { - set: function(value) { + const boundFunction = function() { + const value = fn.bind(element)(); if (component[binding.componentMemberName] !== value) { component[binding.componentMemberName] = value; } - if (getValue() !== value) setValue(value); - }, - get: getValue - }); - component[binding.componentMemberName] = getValue.bind(element)(); + if (descriptor.value['fn']) descriptor.value(); + }; + boundFunction['fn'] = fn; + + Object.defineProperty(context, binding.contextMemberName, { + value: boundFunction + }); + + boundFunction(); + } else { + let getValue = descriptor.get || (() => descriptor.value); + let setValue = descriptor.set || (value => (descriptor.value = value)); + + Object.defineProperty(context, binding.contextMemberName, { + set: function(value) { + if (component[binding.componentMemberName] !== value) { + component[binding.componentMemberName] = value; + } + if (getValue() !== value) setValue(value); + }, + get: getValue + }); + + component[binding.componentMemberName] = getValue.bind(element)(); + } }); //bind Events