Developing AJAX Web applications with Castle Monorail - PowerPoint PPT Presentation

1 / 23
About This Presentation
Title:

Developing AJAX Web applications with Castle Monorail

Description:

AjaxHelper.BuildFormRemoteTag('/Heroes/CreateHero.rails', '%{update='heroList' ... { var r=new Ajax.Request('/Heroes/DeleteHero.rails', {method: 'get', asynchronous: ... – PowerPoint PPT presentation

Number of Views:471
Avg rating:3.0/5.0
Slides: 24
Provided by: gojko
Category:

less

Transcript and Presenter's Notes

Title: Developing AJAX Web applications with Castle Monorail


1
Developing AJAX Web applications with Castle
Monorail
  • David De Florinier
  • Gojko Adzic (gojko_at_gojko.com)?
  • Skills Matter
  • 12/06/08

2
Why Monorail for Ajax Apps?
  • Plumbing handled by the framework
  • Lots of helpers
  • Integrated with Prototype and Scriptaculous
  • Benefits from Castle Project integrations

3
  • Write AJAX apps without much more code than if
    you were writing a
  • non-ajax one!

4
  • Options for AJAX with Monorail
  • Preparing the application
  • Proxying calls
  • Monorail helpers and effects
  • How it all comes together
  • Some best practices and pitfalls

5
Option 1 Rails-style JS Generator
  • Ajax actions send commands to the page
  • Use NJS views instead of VM for Ajax Actions
  • Mix and match Ajax and Non-Ajax calls
  • Reuse partial templates

6
Option 2 Use Prototype and build parts of the
page with actions
  • Ajax actions build only parts of the page
  • Use AjaxHelper to coordinate calls
  • Coordinate page updates from the browser side
  • Cleaner code on the server, more focused
  • Option to use JSONHelper to render results
  • Option to use controller proxies

7
Option 3 Transparent JSON controller binding
  • Actions exported to the web page
  • Coordinate rendering on the client
  • Clean code, all plumbing done by MR
  • Use JSonReturnBinder and JSonBinder
  • ... but not yet complete

8
Preparing the application for AJAX
  • Add prototype.js library
  • AjaxHelper.GetJavascriptFunctions()?
  • ... will render ...
  • src"/MonoRail/Files/AjaxScripts.rails"
  • Use Ajax.Request and Ajax.Updater

9
Use AjaxHelper to create elements
  • AjaxHelper.ButtonToRemote("Delete",
    "DeleteHero.rails", " Complete'heroActionCallba
    ck(request)' , with'\'iditem.Id\'' ")?
  • ... will render ...
  • Ajax.Request('DeleteHero.rails',
    onCompletefunction(request)
    heroActionCallback(request) ,
    asynchronoustrue, evalScriptstrue,
    parameters'id3') return false"/
  • Methods provided for links, buttons, observers,
    autocompletion, forms

10
Use AjaxHelper to Build Forms
  • AjaxHelper.BuildFormRemoteTag("/Heroes/CreateHero
    .rails", "update'heroList',formid'heroForm',
    Complete'document.pageHelper.heroes.listRefreshed
    ()'")?
  • ... will render ...
  • CreateHero.rails" enctype"multipart/form-data" on
    submit"new Ajax.Updater('heroList',
    '/Heroes/CreateHero.rails', onCompletefunction(r
    equest) document.pageHelper.heroes.listRefreshed
    () , asynchronoustrue, evalScriptstrue,
    parametersForm.serialize(this)) return
    false"

11
AjaxHelper parameters
  • with
  • form
  • update
  • success/failure
  • evalScripts
  • complete
  • onSuccess/onFailure
  • before/after/condition

12
Preparing controllers for AJAX
  • Implemented as a method on the controller
  • Tightly focused
  • Promotes reusability
  • Reduces risk due to change
  • Simplifies unit tests

13
Generating controller proxies
  • Decorate methods with AjaxAction attribute
  • AjaxAction
  • public void DeleteHero(int id)
  • Use AjaxHelper.GenerateJSProxy
  • AjaxHelper.GenerateJSProxy("controllerProxy")?
  • .. then the following is rendered
  • var controllerProxy
  • deleteHero function(id, callback)
  • var rnew Ajax.Request('/Heroes/De
    leteHero.rails', method 'get', asynchronous
    !!callback, onComplete callback, parameters
    '_\x26id'id'')
  • if(!callback) return
    r.transport.responseText

14
Synchronous / asynchronous calls
  • Proxies allow both synchronous and asynchronous
    calls to be made
  • Supply a callback function to make asynchronous
    call
  • function heroActionCallback(result)
  • var response result.responseText.evalJSON()
  • alert(response.message)
  • function deleteHero(id)
  • controllerProxy.deleteHero( id,
    heroActionCallback)

15
Synchronous / asynchronous calls
  • Use synchronous calls ONLY if you don't want
    anything else to happen
  • Prefer async calls for better performance
  • Async replies can come in different order
  • Number of simultaneous calls to the same domain
    is very limited

16
Monorail layout strategies
  • Monorail has a concept of layouts
  • AJAX actions would not have a layout
  • ... but index method would
  • There is more than one way to achieve this
  • Two methods illustrated
  • NJS templates don't use layouts (JS Generation)?

17
AJAX layout strategy 1
  • No layout on the class
  • Index method has a layout
  • Layout("default")
  • public void Index()?
  • Simple, quick, no additional code
  • ... but ties the action to blank layout for all
    calls

18
AJAX layout strategy 2
  • Use filter to kill layout on AJAX calls
  • public class AjaxLayoutFilter IFilter
  • public bool Perform(ExecuteEnum exec,
    IRailsEngineContext context, Controller
    controller)
  • if(IsAjaxRequest(context))
    controller.CancelLayout()
  • return true
  • //from http//blechie.com/
  • public static bool IsAjaxRequest(IRailsEng
    ineContext context)
  • string requestedWith
    context.Request.Headers"X-Requested-With"
  • if (string.IsNullOrEmpty(requestedWith
    )) return false
  • return requestedWith.Equals("XMLHttpRe
    quest",StringComparison.InvariantCultureIgnoreCase
    )

19
Script.aculo.us integration
  • A JavaScript framework which is for UI sugar.
  • Install scripts using ScriptaculousHelper.Instal
    lScripts()?
  • Add effects using the ScriptaculousHelper
    VisualEffect method
  • ScriptaculousHelper.VisualEffect('ToggleBlind',
    'colOne')?
  • ScriptaculousHelper.VisualEffect('ToggleAppear',
    'colThree')?
  • ScriptaculousHelper.VisualEffect('ToggleBlind',
    'colTwo')?

20
Script.aculo.us Drag Drop
  • Make elements draggable
  • new Draggable(element, reverttrue)
  • Make elements Drop zones
  • Droppables.add( element, hoverclass
    'dropHover', accept 'dropelementclassname',
    onDrop dropPower )
  • Drop delegate accepts both elements as parameters
  • function dropPower(draggable,droparea)

21
Stuff to remember
  • JSON binding will probably be complete soon
  • Use context for generic shared templates
  • Use AjaxHelper for Prototype integration
  • Use ScriptaculousHelper for effects
  • You can use Prototype and Scriptaculous in JS
    code directly
  • Use async calls for better performance

22
... a few links
  • http//www.castleproject.org/MonoRail
  • http//hammett.castleproject.org
  • http//www.ayende.com/blog
  • http//www.prototypejs.org
  • http//script.aculo.us

23
What next?
  • Beers straight away
  • ALT.NET meeting next week
  • TDD with Databases in two weeks
  • ALT.NET talk at Skills Matter on July 31st
Write a Comment
User Comments (0)
About PowerShow.com