Search code examples
spine.js

Spine.js rendering view


I've just started using spine and I'm having trouble understanding a few things...

class Spk.Register extends Spine.Controller
  render: ->
    @html("<h1>Registration!</h1>")

...

Zepto(function($) {
  new Spk.Register({
    el: $("#data")
  });
});

...I was expecting this to replace any html in the #data element with the html passed to @html when the controller is instantiated, but it doesn't, nothing happens at all.

I've also tried putting the render method in the constructor function but again nothing happens.

How would I replace the html in body with given html when the controller is instantiated?


Solution

  • The problem is the render() method isn't called.

    You have to call it explicitly after controller instantiated.

    Anyway, I think you shouldn't do any rendering in the constructor. Better option is:

    • to have a model (MVC architecture) which triggers particular event after the data loaded from the server,
    • the controller should define event handler for that event and it will render the view.

    EDIT Just very simple code snippet how it could be (CoffeeScript, using jQuery):

    The Task model class:

    class Task extends Spine.Model
    
      @configure 'Task', 'name', 'deadline'
    
      @fetch () ->
        Task.deleteAll()
        # ... load data from the server ...
        Task.create name: 'foo', deadline: '2012-11-22' # create local instance(s)
        Task.trigger 'data-loaded'
        return
    

    The controller:

    class Tasks extends Spine.Controller
    
      constructor: ->
        super
    
      init: () ->
        @routes
            'list': (params) ->
                Task.fetch()
                return
        Task.bind 'data-loaded', () => 
            @render()
            return
        return
    
    render: () ->
        @el.render Task.all()
        return
    

    The initialization code (another possibility could be Spine.js controller stack):

    tasksCtrl = new Tasks el: $('.task-list')
    tasksCtrl.navigate 'list'
    

    Note that it requires also route.js (included in Spine.js) and I've used Transparency template engine (it's @el.render() meth). Then the template looks like:

    <div class="task-list">
        <div class="task">
            <span data-bind="name"></span>
            <span data-bind="deadline"></span>
        </div>
     </div>