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
// component middleware
ko.router.use((ctx) => {
  Object.defineProperty(ctx, 'component', {
    set(component) {
      ko.components.register(ctx.canonicalPath, component)
      ctx.route.component = ctx.canonicalPath
    }
  })
})

// title middleware
ko.router.use((ctx) => {
  Object.defineProperty(ctx, 'title', {
    set(title) {
      document.title = title
    }
  })
})

class App {
  constructor() {
    this.routes = {
      '/': (ctx) => {
        ctx.title = 'Home'
        ctx.component = {
          template: '<h1>Welcome to my App!</h1>'
        }
      }
    }
  }
}

or, with a little fp magic...

import { curryRight, extend } from 'lodash'

const setView = curryRight(extend, 2)

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

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

ko.router.use(createSetterMiddleware('title', (t) => {
  document.title = t
}))

class App {
  constructor() {
    this.routes = {
      '/': setView({
        title: 'Home',
        component: {
          template: '<h1>Welcome to my App!</h1>'
        }
      })
    }
  }
}

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

Clone this wiki locally