Is there an event that fires after the DOM is updated as the result of an observed property? - dart

Is there an event that gets fired after the DOM is updated as the result of an observed property being changed?
Specifically, I need to alter the scrollTop property of a container to show new content as it's added. I have to use a timeout now to wait until the DOM is updated before setting the scrollTop to the new scrollHeight.

Thanks for the question. From my understanding, the changes propagate through the models and DOM asynchronously. It's not clear there is one "ok, literally everything all the way through is done updating" event (I could be wrong).
However, I've used Mutation Observers to know when something in my DOM changes. If you're able to watch a specific place in the DOM for a change (or changes), try Mutation Observers: https://github.com/sethladd/dart-polymer-dart-examples/tree/master/web/mutation_observers
Here is an example:
MutationObserver observer = new MutationObserver(_onMutation);
observer.observe(getShadowRoot('my-element').query('#timestamps'), childList: true, subtree: true);
// Bindings, like repeat, happen asynchronously. To be notified
// when the shadow root's tree is modified, use a MutationObserver.
_onMutation(List<MutationRecord> mutations, MutationObserver observer) {
print('${mutations.length} mutations occurred, the first to ${mutations[0].target}');
}

Related

ChildAdded with LimitToLast triggers ChildRemoved

Regarding Firebase documentation if you limit your query with "toLast" then when a child is added, if you already exceed the value (in my case f.e. 50) then child removed is also triggered because the first child is deleted from the scope.
The following listeners are the ones I have on the code:
firebaseReference.queryOrderedByKey().queryLimited(toLast: 50).observe(.childAdded...
firebaseReference.queryOrderedByKey().queryLimited(toLast: 50).observe(.childRemoved...
I would like to know if there is some way to differenciate when a child is really deleted or a child is just deleted from the scope.
Thank you so much,
any further information don't hestiate to ask.
Firebase does not send along information on why you're receiving the .childRemoved event, so there's no way to know it based on that.
The only thing I can quickly think of is adding a .value listener for each child, which will then fire with null when the child gets deleted.
You'll want to remove the .value listener after you receive the .childRemoved handler, to not have dangling listeners for each child you've ever seen, so this may become more work than it's worth.

Breeze entity manager "hasChanges" property - how do I find out what is triggering the "true" state?

I have the following event handler in my datacontext:
manager.hasChangesChanged.subscribe(function (eventArgs) {
hasChanges(eventArgs.hasChanges);
});
and in Chrome I've set a break point on the "haschanges(eventArg.haschanges);" line.
The moment I load my app and the process of fetching data begins, this breakpoint is hit. It then proceeds to be repeatedly hit and the "hasChanges" property varies between "true" and "false" many times.
I know from further debug breakpoints that a simple query that "expands" a related table via its navigation property triggers a visit to my "hasChangesChanged" event handler.
What I don't know - as the "eventArgs" is so big and complex - is exactly which of my 5 or so related entities being retrieved is triggering the "true" on the "hasChanges" property. Is there a property within the eventArgs I can inspect to determine which current entity has caused the trip to the hasChangesChanged event handler?
I'm puzzled about why any of what I'm doing is setting "hasChanges" to true as all I do in the first instance is retrieve data. As far as I'm aware, nothing is changed whatsoever at the point the entity manager is convinced that something has changed.
To elaborate, my app prefetches lots of data used for a tree structure at the point where it is sitting waiting for first input from the user. As the user has not had an opportunity of touching anything in the app by this point, why would breeze think that any of the entities concerned have been changed when they've simply been read in from the database?
Use the EntityManager.entityChanged event if you want fine grained information about what has changed. This event gives much more detail but is fired much more often.
http://www.breezejs.com/sites/all/apidocs/classes/EntityManager.html

Is there an event to watch for on pushObject?

I'm programmatically pushing an object (using pushObject) into a list that is sortable. My problem becomes that if I try $(selector).sortable('refresh') or $(selector).sortable('serialize') the serialize doesn't contain the recently added dom item. I can console.log($(selector)) and it seems to know that the dom item has been added though.
My original thought is there an event to watch for once pushObject has finished? Or a callback?
Is there an event to watch for on pushObject?
Easiest way to do this is add an observer that fires when the list length has changed. But probably that's not gonna be enough in this case.
It sounds like this is a timing issue. If you try to call refresh right after pushObject (or even in an observer) the refresh code is going to run before the dom has been updated.
The trick is to make sure you are calling $(selector).sortable('refresh') after the new elements have been written to the dom. That could be from a didInsertElement hook on the dom item's view or from an observer, but as #Luke reminded me in comments best way to do it is by scheduling refresh to run after render has completed. Something like:
Em.run.schedule('afterRender', this, this.refreshSortable)

Emberjs - Temporary disable property changes notification

Is there any simple way to achieve a temporary disabling of notifications of an object property or properties?
I know you can defer them with beginPropertyChanges() and endPropertyChanges() but I don't want those changes to be notified at all until I explicitly enable them.
Thank you in advance.
Use case:
I have to set a property of an object (A) with another object (B). Properties of B are being observed by several methods of other objects. At some time the B object's data gets cleared and the observers get notified, later an HTTP response sets them with something useful. I would not want the observers get notified when clearing the object because the properties values are not valid at that moment.
Ember doesn't support suspending notifications. I would strongly suggest against toying with the private APIs mentioned in the above comments.
I wonder why you bother clearing the object's data prior to the HTTP request? Seems strange.
Using a flag will cause the computed to still trigger.
The best I've come up with is to override the computed with the last known value. Later you can enable it by setting the computed property definition again.
let _myComputedProperty = Ember.computed('foobar', function() {
let foobar = this.get('foobar');
console.log('myComputedProperty triggered >', foobar);
return '_' + foobar + '_';
});
Controller.extend({
turnOffComputed: function() {
let myComputedProperty = this.get('myComputedProperty');
this.set('myComputedProperty', myComputedProperty);
},
turnOnComputed: function() {
this.set('myComputedProperty', _myComputedProperty);
}
})
Full example: Conditional binding for a computed property
This is an old question, but it appears high in Google search for suspending observers, so I would comment.
There are evident use cases for such a feature, for example, an enum property of an object is represented by a list box and the object may change. If the list box is used to request property changes from the server and to set the new value on success, the natural way to do things is to use a controller property with the list box, set that property to the object property when the object changes, and observe it to make requests to the server. In this case whenever the object changes the observer will receive an unwanted notification.
However, I agree that these use cases are so diverse that there is no way Ember can support them.
Thus, a possible work around is to declare a variable in the controller and use it whenever you change a property so that you react only to changes made by the User:
doNotReact: false,
updateManually: function() {
this.doNotReact = true;
Ember.run.scheduleOnce('actions', this, function() {
this.doNotReact = false;
});
............
this.set('something', somevalue);
............
},
onChange: function() {
if (this.doNotReact) return;
...............
}.observes('something')
The value of doNotReact will be reset after the observer gets a chance to run. I do not recommend to reset the stopper variable in the observer since it will not run if you set the property to the same value it already has.

Jquery Mobile: Can I use stopPropagation in the pagebeforehide handler?

On one of my pages, I want to ask users first whether they want to navigate away. When user answers no, no transition should occur.
I tried this code:
$('#pTakeCardSet').live('pagebeforehide',function(event, ui){
event.stopPropagation();
});
But it doesn't work. The new page is still loaded.
Does anyone have the same problem?
You may be getting bit by a live event - from : http://api.jquery.com/event.stopPropagation/
Since the .live() method handles
events once they have propagated to
the top of the document, it is not
possible to stop propagation of live
events. Similarly, events handled by
.delegate() will always propagate to
the element to which they are
delegated; event handlers on any
elements below it will already have
been executed by the time the
delegated event handler is called.

Resources