Rivets and Spine js example

可紊 提交于 2019-12-13 04:57:39

问题


I am working on a Spine App that users rivets js in lieu of a templating engine and so far I am delighted with the rivets bindings, my views are more concise and readable and I have a clean separation of concerns: my controllers only take care of managing the state of the app, my models do the persistence stuff and my custom rivet bindings and formatters take care of formatting values and massaging user input. So far so good.

My only concern is that I am using watch.js and I suspect watch is responsable for iphone performance issues, and I not too comfortable using it.

In rivets js site it states that it has support for Spine although I haven't been able to find a single example let alone a snippet.

The only adapter that works both for controllers and models I could come up with is this:

rivets.configure adapter:
  subscribe: (obj, keypath, callback) ->
    watch obj, keypath, callback

  unsubscribe: (obj, keypath, callback) ->
    unwatch obj, keypath, callback

  read: (obj, keypath) ->
    obj[keypath]

  publish: (obj, keypath, value) ->
    obj[keypath] = value

Is there a better way to binding rivets to spine models and controllers?

I've been struggling with Object.defineProperty to no avail.


回答1:


Spine.js doesn't emit events when you change attributes on the model, it only fires an event when you call save() on the model. It also doesn't perform any sort of dirty tracking, so you don't get update:keypath style events out-of-the-box, it just fires a single update event.

Here's a standard adapter for using Spine.js models with Rivets.js.

rivets.configure
  adapter:
    subscribe: (obj, keypath, callback) ->
      obj.bind "update", callback

    unsubscribe: (obj, keypath, callback) ->
      obj.unbind "update", callback

    read: (obj, keypath) ->
      obj[keypath]

    publish: (obj, keypath, value) ->
      obj[keypath] = value

Using the above adapter, Rivets.js will update the in-memory attributes on your models when going from view-to-model (using a two-way binder such as value or checked) and will update the view (going from model-to-view) only when you call save() on the model. This is just part of how Spine.js events work.

Unfortunately the above adapter will update every binding for that model, including bindings for properties that did not change. Alternatively, you can use something like Spine-Attribute-Events which does basic dirty tracking and fires an additional update:keypath style event for the attributes that changed. This will be far more performant in terms of DOM operations as we're only updating what needs to be updated.

rivets.configure
  adapter:
    subscribe: (obj, keypath, callback) ->
      obj.bind "update:" + keypath, callback

    unsubscribe: (obj, keypath, callback) ->
      obj.unbind "update:" + keypath, callback

    read: (obj, keypath) ->
      obj[keypath]

    publish: (obj, keypath, value) ->
      obj[keypath] = value

As you can see, this gives Rivets.js a more granular way to subscribe to individual attribute changes. The basic idea here is that Rivets.js will now update only the parts of the DOM for attributes that have changed.

Again all of this happens only when you call save(), which is actually a nice feature because you can make as many intermediate changes to the model as you want, and then call save() at the very end to have those changes reflected in the UI.




回答2:


I am not the expert, but that seems to be a correct adapter configuration file for Watch.js.

But that may not be your performance problem. Try this link for more performance hints: How to bind deeper than one level with rivets.js



来源:https://stackoverflow.com/questions/16956638/rivets-and-spine-js-example

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!