ripplejs/ripple

Firing events/methods when data changes

Closed this issue · 14 comments

Following Anthony's suggestion, im posting this question here since there isn't yet a StackOverflow or forum where this kind of request probably fit better.
Hope you don't mind and can point some directions to where look further.

Im trying to build a small component, based on the iteration example, where I have a list of numbers that I can add or remove items.

I've published the working sample here:
http://jsfiddle.net/lmartins/VPB93/

Let's say I wanted to achieve the following:

  • When no items on the list show a "no items" message instead - This would happen of first page load and if the user deleted all items

What would you suggest doing to achieve this, I though of custom events or setting an watcher on the items array using the observer plugin but im still lacking the knowledge to figure how all the parts fit together.

I'd probably just use hidden attributes. Let's say the template kinda looks like this

<div each="{{ items }}"></div>
<div hidden="{{ !item.length }}">No items to show</div>

That's probably the easiest way for that.

hidden is a HTML thing, I think IE doesn't automatically set it to display:none though, but you can usually safely add that as a global style

Thanks for the suggestion Anthony.

But what if I also needed some logic to toggle the state of the "order" and "delete all" buttons, how would you hook that?

Sent from my iPhone

On 26/04/2014, at 19:59, Anthony Short notifications@github.com wrote:

hidden is a HTML thing, I think IE doesn't automatically set it to display:none though, but you can usually safely add that as a global style


Reply to this email directly or view it on GitHub.

Depends on the sort of logic. If it's just whether there are any items, I'd just do <button disabled="{{ !items.length }}"></button>.

Otherwise if there's more logic around it, you could use computed properties or just listen for changes to the items array.

CustomSMS.created ->
  @data.items.on 'change', =>
    if @data.items.length then @set 'canDeleteAll', true

(My coffeescript might be a little rusty)

The array fires a change event whenever the length changes. So you could check it, and then set a property. Then use that in the template:

<button hidden="{{ !canDeleteAll }}"></button>

Cool, that gives me a path to explore.
The inline properties would do fine for my sample, but my goal here is more to understand how can I wire things up with ripple for future cases.

Thanks again Anthony, I'll close this issue once I'm on my computer.

Cheers.

Sent from my iPhone

On 26/04/2014, at 23:33, Anthony Short notifications@github.com wrote:

Depends on the sort of logic. If it's just whether there are any items, I'd just do .

Otherwise if there's more logic around it, you could use computed properties or just listen for changes to the items array.

CustomSMS.created ->
@data.items.on 'change', =>
if @data.items.length then @set 'canDeleteAll', true
(My coffeescript might be a little rusty)

The array fires a change event whenever the length changes. So you could check it, and then set a property.


Reply to this email directly or view it on GitHub.

Two quick questions Anthony,

  1. Does that created() function supposed to be in the the CustomSMS prototype?
  2. Do I need to setup any watcher on the array or it does emit the change events out of the box?

Thank you.

  1. Nope, that's just shorthand for CustomSMS.on('created'... blah blah. But it binds this to the view. That functionality is a little confusing and will probably just be a plugin soon
  2. Nope, when you use the each plugin it turns arrays into event emitters. So you have the .on, .off and .emit methods

Ok, I think i'll wait for clarification in the docs, while doing some more testing.

I still didn't get it to work, having some scope issues, because the @data.items is returning undefined on the scope it is running. Not sure why because doing a console.log(this) inside the "on" event does return a function View that contains a this.data = this.model.props

Another thing i've noticed, not sure if it is normal, is that the event fires 4 times (1 + 3), apparently what it is happening is that the event fires when the view is first created and then one time for each item in the data.items array.

Within the event handler this will just be the global scope since it isn't bound to anything. That's pretty standard for event emitters. But you get passed a view.

The second one is a bug, I've added it to my list of things to fix up tonight :)

Ok, im closing this now while im investigating why I can't bind the change to the data.items array.

Thanks for all the help.

Pretty sure the issues you're having are directly related to #21. The each plugin was built pretty quickly and definitely needs some work.

I believe so, yes, the errors im getting happen on the second time the event fires, which by then is bound to the data.items array iteration and not the the main view.

Yup! It's here https://github.com/ripplejs/each/blob/master/index.js#L45

Need to make that have it's own View rather than re-using the parent one.

Cool, definitely I'm learning something here despite the frustration of being unable to make it work :-)