Skip to content
This repository was archived by the owner on Dec 19, 2017. It is now read-only.

Using Middleware to Create Declarative Views

Casey Webb edited this page Dec 16, 2016 · 7 revisions
const componentSetterMiddleware = (ctx) => {
  Object.defineProperty(ctx, 'component', {
    set(component) {
      ko.components.register(ctx.canonicalPath, component)
      ctx.route.component = ctx.canonicalPath
    }
  })
}

const titleSetterMiddleware = (ctx) => {
  Object.defineProperty(ctx, 'title', {
    set(title) {
      document.title = title
    }
  })
}

const homeView = (ctx) => {
  ctx.title = 'Home'
  ctx.component = {
    template: '<h1>Welcome to my App!</h1>'
  }
}

ko.router.use(componentSetterMiddleware)
ko.router.use(titleSetterMiddleware)

ko.applyBindings({
  routes: {
    '/': homeView
  }
})

or, with a little fp magic...

import { curryRight, extend } from 'lodash'

const view = curryRight(extend, 2)

const createSetterMiddleware = (prop, middleware) => (ctx) => {
  Object.defineProperty(ctx, prop, {
    set: (v) => middleware(v, ctx)
  })
}

const componentSetterMiddleware = createSetterMiddleware('component', (c, ctx) => {
  ko.components.register(ctx.canonicalPath, component)
  ctx.route.component = ctx.canonicalPath
})

const titleSetterMiddleware = createSetterMiddleware('title', (t) => {
  document.title = t
})

const homeView = view({
 title: 'Home',
 component: {
   template: '<h1>Welcome to my App!</h1>'
 }
}) 

ko.router.use(componentSetterMiddleware)
ko.router.use(titleSetterMiddleware)

ko.applyBindings({
  routes: {
    '/': homeView
  }
})

You did learn you a Haskell for great good, right?

Clone this wiki locally