akrymski/espresso.js

Possible bug or I'm confused.

Closed this issue · 15 comments

Edit: NVM, you can close this....

it turns out it was my fault; if you use syntax
for (i in arr){
collection.push({id: i, ...})
console.log(i, typeof i)
}
you'll see JS uses a string type for index, and that breaks the collections update/find Fn's

sorry.....

Hi I'm a little confused on Collection.set and Collection.push, can you tell me if this is a bug?

Anyway If you use collection.push({id: 9999, otherfield: 1234})
collection.set({id: anyid, ...}) no longer works... I assume this is because either you cannot set the ID from push, you cannot start above 0, or you cant use abritrary IDs from the backend ^_^.

  1. What is the correct way to add an item to collection, .push()? Is it without specifying an id?
  • I am using push({ id: 9999, otherfield: 1234, otherfield2: 1234 }), and i'm using Ids > 0 as my first item, I think this is causing the problem
  1. What is the correct way to update one field of one item to that collection?
  • If I do collection.set({ id: 1, field2: 'newdata'}), sometimes the entire object is replaced with this new smaller object (now only has these 2 fields) but usually nothing happens and .get(id) returns the old values

Maybe you can update the docs to be a little more clear? This is a great lib

After more testing it seems that:

  • if you use push and dont have an id attrib
  • or if you use push and the first id in the collection is > 0

the .set({id: x, ...}) notation will not work. .set(index, {...}) still does

Not sure if its a bug, the docs should probably say what you can and cant do here, I was probably just being lazy using ids from the backend to make my life easier...

Not sure what you mean ... you can use strings or ints for IDs it still works for me:

var c = new Espresso.Collection()
c.push({ id: '9999', otherfield: 1234, otherfield2: 1234 })
c.set({ id:'9999', otherfield: 'x', newfield: 1234 })
c.get({ id: '9999' }) 

{
id: "9999"
newfield: 1234
otherfield: "x"
otherfield2: 1234
}

yea it was because i was using something like this--

a.push({id:'3', a:2, b:2})
a.get({id:3})

oh I see, of course the IDs are checked using the === operator

this is honestly the best framew ive seen...

ive written a few 1 page apps to test it so far. the first one sucked, the 2nd one kind of amazed me how little code i had to write and how well it worked. the third one was really fast. today for my 4th app i rewrote an app that took me 1 month of coding in mostly jquery. i rewrote it in about 4 hours... instead of 50.. lol. 160 lines of js vs about 600... and the html is about 50% of the old one.

not sure if im gonna push it into production or stick with jSpaghetti, but for the evaluation this lib is really totally handy. the click handlers work really nice... any idea on performance once there are hundreds or more on the screen? can you tell me how they are bound to the view?

very good job on this. thanks a lot.

We use this framework for mobile app development, so it’s very much performance focused. It should perform better than most other frameworks, and if you find otherwise - I’ll fix it. I strongly suggest you read the source as it’s only 500 lines and you’ll understand exactly how it works once you do (the point is in the simplicity of knowing exactly what happens under the hood). At least read the render() method - it’s super short. Here’s the benchmark from ToDoMVC perf test:

screen shot 2014-11-10 at 15 46 14

Whilst it’s a very specific test case and we haven’t optimised the To-Do example app at all, it’s still the 2nd fastest framework out there, and should be 2-4x faster than Angular & React.

Click handlers are just bound with addEventListener to that node - the vanilla js approach. We found that it performs better than using event delegation style binding which jQuery & Backbone uses: whilst it may consume a tiny bit more RAM cause you end up binding a few more handlers (which depends on the browser really) the events get triggered much faster as you no longer have to traverse the DOM from the target to check which nodes have been actually clicked. This is especially helpful on mobile when you want to react to touch events instantly.

Thanks for your feedback!

On 4 Dec 2014, at 15:56, falafflepotatoe notifications@github.com wrote:

this is honestly the best framew ive seen...

ive written a few 1 page apps to test it so far. the first one sucked, the 2nd one kind of amazed me how little code i had to write and how well it worked. the third one was really fast. today for my 4th app i rewrote an app that took me 1 month of coding in mostly jquery. i rewrote it in about 4 hours... instead of 50.. lol. 160 lines of js vs about 500... and the html is about 50% of the old one.

not sure if im gonna push it into production or stick with jSpaghetti, but for the evaluation this lib is really totally handy. the click handlers work really nice... any idea on performance once there are hundreds or more on the screen? can you tell me how they are bound to the view?

very good job on this. thanks a lot.


Reply to this email directly or view it on GitHub #8 (comment).

One thing I cant figure out is how to access the parent obj or go up one item in the hierarchy,

for example: controller button < controller popupwindow < controller app

if im in button.dostuff(), how can i call popupwindow.something()? popupwindow is actually a dynamic item so i cant peg it to a global variable

Controllers should emit DOM events which bubble up the tree.

https://developer.mozilla.org/en/docs/Web/API/CustomEvent

Then you can use listenTo method of the controller to listen to those events.

On 8 Dec 2014, at 07:04, falafflepotatoe notifications@github.com wrote:

One thing I cant figure out is how to access the parent obj or go up one item in the hierarchy,

for example: controller button < controller popupwindow < controller app

if im in button.dostuff(), how can i call popupwindow.something()? popupwindow is actually a dynamic item so i cant peg it to a global variable


Reply to this email directly or view it on GitHub.

great thanks i got that to work, can i ask how you would pass the id or copy of the controller along with it as well? ie dispatchEvent('myevent', { fromcontroller: this })

atm.. the best i can do is dispatchEvent('show', { fromitem: 6 }) -- which is what im going to do - but im not sure if thats best.

im not really sure how to properly store/find a dynamically created controller ie app.list.item7.highlightme() (because the id is in the model and the fn is in the controller... what am i doing wrong?)

its not normally this hard, im making a websocket app though so mostly its server controlled instead of view controlled..
sorry noob questions, i just found out abt backbone and espresso ;D

Not quite sure what you mean. You really don't want to pass references to controllers in general, what are you trying to achieve? Perhaps it could be done by passing a DOM node instead for example?

Can i access the controller again from the dom node?

My app has a lot of server fed data streamed to it, so often on a server data push i have to do stuff in the app window, then dig down to one list item and do jquery animation.

Since its awful jquery animation right now I have the code in a function in the list controller (anim()).. so im wondering if while im updating the app window I can do this.list.find({id:1}).anim() -- but i cant?

The same goes for going up in the tree - If i have a list item that is just a button - when clicked I want to do parent.doajaxstuff(withOtherParentData) -- but there is no parent property -- and the parent is actually a template also (4 per window now) so it will be in a list or collection soon. once its virtualized the current method im doing window.app.panel1.doajaxstuff() wont work

not sure how to handle this, any suggestions? I guess this is more meteor js like with bunch of server pushes and publish/subscribe data... The bubble custom event does work, so now I just need to access the controller again from the dom or from my list, so i can call my animate()

Not entirely sure what you mean without seeing code.

Your models should raise events that controllers listen to. So you’d have a ListItemController that listens to the window events for example:

this.listenTo(window, 'animateItem', function(e) {
  if (e.id === this.model.id) this.animate()
})

A button in a list should simply trigger an event that bubbles up the DOM, and you can have the parent catch it. You can pass any data you like in the event, including the reference to the controller if you really want to.

ok thanks :)

one more question for ya...

how do i do render something like this...

render: func() { return {
    mylistdiv: { view: this.list, onclick: this.clickedlist }

view isnt the right attr name there im not sure what it is? of course "mylistdiv: this.list" renders fine...

just wrap the list in another element:

render: function() {
return {
wrapper: this.clickedlist
mylistdiv: this.ist
}

On 14 Jan 2015, at 05:07, falafflepotatoe notifications@github.com wrote:

one more question for ya...

how do i do render something like this...

render: func() { return {
mylistdiv: { view: this.list, onclick: this.clickedlist }
view isnt the right attr name there im not sure what it is? of course "mylistdiv: this.list" renders fine...


Reply to this email directly or view it on GitHub #8 (comment).