model.on with wildcards

84 views
Skip to first unread message

Oliver

unread,
Jun 20, 2013, 2:50:31 PM6/20/13
to der...@googlegroups.com
I'm using model.on('change', '_page.m.shapes.*.offset', function(value, out, isLocal, passed) { ... }

If the change is a local change, the value field is filled with the content of "*". E.g., if "shape1" is updated, "value" contains "shape1".

If the change is a remote change (passed.$remote = true), the value is undefined. How can I find out the "value" of "*"?

TYIA :)

Oliver

unread,
Jun 21, 2013, 12:04:16 PM6/21/13
to der...@googlegroups.com
The solution is to use model.on in app.enter() and NOT in app.ready() or in app.get().

Nate Smith

unread,
Jun 21, 2013, 2:07:45 PM6/21/13
to der...@googlegroups.com
Model listeners on paths under `_page` are removed between every client side page render. This is a very handy feature and keeps you from running into bugs with state leaking between pages in unexpected ways. app.ready() callbacks only get fired once, after the very first page load, and you generally shouldn't use it unless you know what you are doing and the code should really only run a single time after page load.

app.get() and other routes render on both the client and the server. If it renders on the server, the route does not run again on the client. You should pretty much never put model.on listeners in app.get routes.


--
You received this message because you are subscribed to the Google Groups "Derby" group.
To unsubscribe from this group and stop receiving emails from it, send an email to derbyjs+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Curran Kelleher

unread,
May 13, 2016, 9:05:32 AM5/13/16
to Derby, na...@nateps.com
Hello,

I'd like to listen for changes on a path under `_page` such that my function executes on the client side. How can this be done? It seems like app.enter() has been deprecated. Thank you.

Best regards,
Curran

Carl-Johan Blomqvist

unread,
May 14, 2016, 3:46:39 AM5/14/16
to Derby
There are certain events fired whenever a new page is rendered. You can use bind a fn to app.proto.create which is the same as app.ready used to be (see above). In that fn you can bind to the event (which I don't remember) that triggers whenever the page rerenders/recreates - in that event you do a wildcard binding to _page which should work.

Carl-Johan Blomqvist

unread,
May 14, 2016, 3:49:33 AM5/14/16
to Derby
Check https://github.com/derbyjs/derby/blob/master/lib/Page.js and the render function for two events emitted which could be useful for these purposes.

Matthew Browne

unread,
May 15, 2016, 8:59:30 AM5/15/16
to Derby
On Saturday, May 14, 2016 at 3:46:39 AM UTC-4, Carl-Johan Blomqvist wrote:
There are certain events fired whenever a new page is rendered. You can use bind a fn to app.proto.create which is the same as app.ready used to be (see above). In that fn you can bind to the event (which I don't remember) that triggers whenever the page rerenders/recreates - in that event you do a wildcard binding to _page which should work.

Unfortunately it seems that in Derby 0.6 and above, the app.render event is only fired on the client if the route was rendered on the client. In Derby 0.5 I was able to do the following and the code would run regardless of whether the route was rendered on the client or the server:

app.on('render:demo-route', function() {
model.on('all', '_page.foo', function(eventType, fooVal, oldFooVal) {
...
});
});

I too would be interested to know how to accomplish this in the latest version of Derby.

Carl-Johan Blomqvist

unread,
Jun 7, 2016, 6:37:44 AM6/7/16
to Derby
Looking at the source here: https://github.com/derbyjs/derby/blob/master/lib/Page.server.js and here: https://github.com/derbyjs/derby/blob/master/lib/Page.js it looks like the 'render' event is emitted from the page object nowadays (and reliably both client and server side). Figure out how to get the page object and you should be ready to go!

Curran Kelleher

unread,
Jun 7, 2016, 7:29:25 AM6/7/16
to der...@googlegroups.com
Thanks!

For the record, I ended up solving the issue I was having by creating a component, passing in the property on "_page" into the component, then listening for changes in the model property local to the component.

Regards,
Curran

On Tue, Jun 7, 2016 at 4:07 PM, Carl-Johan Blomqvist <carljohan...@gmail.com> wrote:
Looking at the source here: https://github.com/derbyjs/derby/blob/master/lib/Page.server.js and here: https://github.com/derbyjs/derby/blob/master/lib/Page.js it looks like the 'render' event is emitted from the page object nowadays (and reliably both client and server side). Figure out how to get the page object and you should be ready to go!

--
You received this message because you are subscribed to a topic in the Google Groups "Derby" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/derbyjs/HnaDFTLzScY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to derbyjs+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Matthew Browne

unread,
Jun 8, 2016, 9:03:34 AM6/8/16
to der...@googlegroups.com
On 6/7/16 6:37 AM, Carl-Johan Blomqvist wrote:
Looking at the source here: https://github.com/derbyjs/derby/blob/master/lib/Page.server.js and here: https://github.com/derbyjs/derby/blob/master/lib/Page.js it looks like the 'render' event is emitted from the page object nowadays (and reliably both client and server side). Figure out how to get the page object and you should be ready to go!
Thanks for pointing that out. Unfortunately, it seems that by the time it's possible to get a reference to 'page', it's too late to set up a listener to the 'route' event on it. Side-note that may be relevant: the client-side App (lib/App.js) sort of inherits from Page (this.proto = this.Page.prototype).

However, I was able to create a model listener that works both on the client and the server. The next step would be to make it page-specific, since the reason to do this would generally be to listen for model changes on a particular page (with the exception of global model variables, e.g. _session.foo).

//this fires when the client-side app first loads
app.on('ready', function() {
    listenForModelChanges();
});

app.on('route', function() {
    if (app.page) { //if rendered on the client
        listenForModelChanges();
    }
});

function listenForModelChanges() {
    var model = app.model;
    model.on('change', '_page.foo', function(newVal, oldVal) {
        log('changed', newVal)
    });
}

Reply all
Reply to author
Forward
0 new messages