About 10 days ago I started to develop a new very dynamic interface
and had to choose some binding framework.
I've worked a bit with Knockout.js in the past and it works great
but I was curious about other alternatives.
So there were lots of good ones: Knockout.js, Angular.js, Ember.js
and Serenade.js.
Ember has lots of features I don't need, so I skipped it for now.
Among the other approaches,
I appreciate that KO is not logic-less and I like to have some
simple logic in my views, but on the other side, Serenade's source
is written with CoffeeScript and this is mostly the reason why I
chose to give it a try.
But I'm experiencing lots of bugs with Serenade in those last days
and have fixed some IE7 compatibility issues that are required for
an important client of my company.
Some of the fixes don't seem to get reviewed yet. Should I announce
them here?
Mostly I'm pretty happy with Serenade as it allowed me to develop my
application in a quite fast rhythm, although I was also slowed down
by some bugs. But I'd like to thank you for Serenade anyway.
Today I experienced an issue that I'd like to ask your help on
understanding what is happening and what I'm supposed to do.
I need to develop a dynamic tree and there will be some buttons in
some of the nodes. When clicked a dialog must be opened, which is
created on the controller.loaded method where I can access the view.
There is a hidden div inside the template for that node and I use it
for generating a jQuery dialog. Then I store this dialog created on
loaded() in the controller instance itself.
The problem is that it seems my controller is being created multiple
times for the same node although the HTML content is kept, but it is
not exactly the same node, which causes lots of trouble.
Let me try to demonstrate some conceptual code:
class MyController
constructor: (@myModel)->
loaded: (_, @view)-> @dialog = @createDialog()
createDialog: ->
$.getJSON aPath(@myModel.get 'id'), (data)->
@myModel.myCollection.push new Item(item) for item in data #
this will populate the div.dialog content before I create the
dialog:
$(@view).find('.dialog').dialog()
openDialog: -> @dialog.dialog 'open'
This is just a simplified version of one of the things my controller
does.
First, I need to be able to render a dynamic template that will
depend on my model instance and Serenade subtemplate won't support
it. It is something like this:
class AbstractModel extends Serenade.Model
@create = (options)->
switch options.type
when 'type1' then new Type1Model(options)
when 'type2' then new Type2Model(options)
else throw "unsupported type: #{options.type}"
@property 'view'
constructor: (@options)->
class Type1Model extends AbstractModel
constructor: -> super *arguments; @set 'view', 'type1'
class Type2Model extends AbstractModel
constructor: -> super *arguments; @set 'view', 'type2'
Then, following the advice in this issue, this is the helper I'm
using:
https://github.com/elabs/serenade.js/issues/43
Serenade.Helpers.dynamicView = (name)-> Serenade.render
@model[name], @model, @controller
But the result of this is that loaded is being called twice in my
controller which is not the behavior I'm looking for.
Other than that, sometimes when I click on a button with click event
attached to controller.openDialog @dialog would be [] in some cases,
probably related to the doubled createDialog.
When I realized that, I've changed my code to something like this:
loaded: (_, view)-> return if @view; @view = $ view; @dialog =
@createDialog()
Then the problem of @dialog being an empty array has gone, but
openDialog didn't work anyway. Calling @dialog.dialog('open') did
nothing under some circunstances but I could see that its content
was correct, although somehow jQuery UI wasn't recognizing it as a
jQuery dialog anymore.
So, I'm pretty confused about what to expect from the controller's
behavior.
Also, I'm missing some built-in caching capabilities in Serenade's
getters:
https://github.com/elabs/serenade.js/issues/54
Another nice-to-have feature would be to be able to do something
like this:
@model.bind 'change', @onChange, 1000 # throttle time
This means that onChange would be called just once as soon as there
has been already 1s elapsed after last change.
Is this the correct place to discuss such issues/features?
I'd really appreciate some help here.
Have a great weekend,
Rodrigo.