MFlow  Create and maintain dynamic Web applications as easy and fast as console applications
Thou shall not write request handlers
 This release: 11/06/2014.  agocorona@gmail.com (@agocorona) <>< . issues & bugs .  Mflow Source code,     source code of this site




Caching AJAX responses to navigate a dataset in the browser using composable caching directives


What is the killer appication of the JavasCript frameworks?  To present data sets without repeated acesses to the server using the new HTML5 cache.

Now the new composable cache policies of MFlow permits the use of aggresive caching policies even for highly dynamic pages, since expressing cache directives is in the hands of the programmer of each particular widget, instead of HTTP gurus. The "separation of concern" preclude the synergies between components.

This example show how the small javascript programs generated by witerate and dField are cached to navigate the infinite dataset of the natural numbers in both directions without roundtrips to the server.

To understand how it works see:

Composable caching: Now the programmer can express independently the caching policies for each widget
  

Running example

(in the light red box):
Read from the server at: 2017-12-16 01:38:05.300868 UTC
1
2
3
4
5
next prev
exit


Source code:

{-# LANGUAGE CPP, DeriveDataTypeable #-}
module CachingDataset where
import Data.Typeable
import Control.Monad
import Data.Time

-- #define ALONE -- to execute it alone, uncomment this
#ifdef ALONE
import MFlow.Wai.Blaze.Html.All
main= runNavigation "" $ transientNav cachingDataset
#else
import MFlow.Wai.Blaze.Html.All hiding(page)
import Menu
#endif
newtype NextReg = NextReg Int deriving Typeable

cachingDataset= do
   page $ iterateResults [1..] 5  **> wlink () << b << "exit"
   where
   iterateResults allnames n= pageFlow "d" $ witerate $  do
      public
      maxAge 200
      time <- liftIO getCurrentTime
      b << "Read from the server at: " ++> dField(wraw . fromStr $ show time) <++ br
      NextReg ind <- getSessionData `onNothing` return (NextReg 0)
      foldl (**>) noWidget [dField(getData i ) <++ br | i <- [ind .. ind + n - 1]]
      r <-     dField (wlink (next ind ) << b << "next" ) <++ fromStr " "
           <|> dField (wlink (prev ind ) << b << "prev")
           <|> restp
      setSessionData $ NextReg r
      where

      getData i =  wraw . fromStr . show $ allnames !! i

      next i  =  i + n
      prev i  = case i >= n of True ->  i - n; _ -> i

comments powered by Disqus