Take a custom realtime object "MyObject" one property of which is an IndexReference referring to a CollaborativeList "MyList". "MyObject" also has a collaborative field property "MyProps" into which I put a json string.
In order to detect changes to "MyProps" I tried the following:
MyObject.addEventListener(gapi.drive.realtime.EventType.OBJECT_CHANGED, dealWithChanges);
However, when I make any change to an object in "MyList", which shouldn't affect the IndexReference in any way, the OBJECT_CHANGED event is fired on "MyObject"
Is this by design? It makes the OBJECT_CHANGED event useless, effectively a "something has changed somewhere" event, but without it there appears no way to detect a change to "MyProps".
Object changed events bubble, so you can listen higher up the tree for anything that is happening lower.
To listen only for changes on collaborative fields within the particular custom object, you want a ValueChangedEvent
Related
I'm building a project using the Backbone global as an event bus. The idea is that a view will trigger a custom event and pass in some data, then whatever collection is listening for that event will use the data to create a model and add that model to itself, and give some kind of message.
I notice that if I start from a new instance of my application and trigger one of these events, then in Chrome Dev Tools, Backbone._events looks something like this: {'add_person': [Object] } and the appropriate event handler runs and processes that one object in the value array. So far, so good.
Now, let's say I trigger that event handler again. What I've noticed is that Backbone._events looks like {'add_person': [Object, Object]} and the event handler runs twice, presumably on both members of the value array, including the first which was already processed.
My question is how do I prevent this behavior, short of binding the event with once and re-binding it after each time it's called? Thanks.
I'm not entirely sure what your setup is, i.e. how you're triggering and listening to these events you're firing but it sounds like you might be doing something like:
GlobalEventBus.on('add_person', this.addPerson, this);
Assuming you're binding to the event using on this could well be your problem if you're not manually unbinding the listener when your view is destroyed.
You're better off using Backbone's listenTo when listening to events that are triggered from an object outside the object you're listening in.
So, for example, in your collection you'd instead have:
this.listenTo(GlobalEventBus, 'add_person', this.addPerson)
Again though, i'm not entirely sure what your setup is.
See this codepen for a working example.
Only one events is triggered each time but keep in mind that only one model is being added because each model is a duplicate and has the same id. Assuming each model was unique it would be added to the collection.
Some further info on listenTo
I am looking for something that fire before the source is update
So instead of Binding.SourceUpdated I want Binding.PreviewSourceUpdated
I think you would need to handle this on your UI element and intercept the event if it's not ideal. So for example say you had a text box and a user pressed a key. You would use the PreviewTextInput (or similar preview) to see if you wanted the data changed - then mark the event has handled if you didn't.
The only other option that I know of is to use DataValidation and not allow the property to be updated for the model side.
Lets consider following example, I have "Document" object which contains collection of "Person" objects and each "Person" object has collection of "Address" objects. When one of the "Address" object changes I need to call server-side method to calculate optimal path between all addresses of a person(whose "Address" was changed) and update user interface. I need to know that one of addresses was changed and person whose address was changed.
The only solution I have so far is to implement some sort of event bubbling. When "Address" object changes it notifies parent("Person" object) about the change, "Person" notifies "Document". Now we can add listener to "Document" class and make required actions. Downside of this approach - I have to manage "parent" links for all the objects in the hierarchy. Can somebody comment on this solution? is it good? Or maybe I am doing something wrong here?
Thanks.
You can manage your own hierarchy using "parent" fields, or you can make the parent object listen to its children and re-dispatch events. This could probably be managed mostly via some shared helper code.
You are on the right track.
When you create the event, just set the bubbles property to true.
http://www.igorcosta.com/flex3/doc/flash/events/Event.html#bubbles
You'll have to add your event listener on the document class in ActionScript [unless you define the event metadata on the Document class], but it should work and bubble w/o problems.
If there is no compelling reason for you to "Catch / re-dispatch" I wouldn't bother to re-create the wheel.
What are some of the practical differences between using the CollectionViewSource.View.Filter property as opposed to the CollectionViewSource.Filter event? Are there situations where you would use one over the other or is it a matter of preference?
Cheers,
Berryl
EDIT:
I do see that the docs say "If your view object comes from a CollectionViewSource object, you apply filtering logic by setting an event handler for the Filter event." although nothing stops you from setting the property on the view, and it doesn't say why to do so.
The advantage I have found so far in setting the event on the CollectionViewSource is that you can implement all of your filtering logic in one event handler and then use View.Refresh (or View.DeferRefresh) to invoke it as the user changes filtering criteria.
Setting the Filter event in the CollectionViewSource would mean that the event is called even when there is no filtering needed which would make the process less efficient.
The official way of using the Filter event is by adding it on filtering and removing it later when the filter is cleared.
viewsource.Filter += viewsource_Filter;
Then:
viewsource.Filter -= viewsource_Filter; //how do you know how many events there are!?
If you use the event, you have to make sure that you are not adding the event each time the filter value changes, because apart from having redundant events lurking around (=app works harder for nothing) you will have to remove all the events in order to clear the filter.
Thus, there is an advantage in using the Filter property, because you can more easily clear the filter by setting the property to null.
viewsource.view.Filter = null;
Like the title says I am trying to architecture into my application a way to distinguish the source of a variable change, either from UI or code-behind.
My problem is that I need to trigger some action after a property changed its value, but I only need to do this when the change comes from the UI because otherwise I don-t want to perform that action. I am having some trouble because, for example when a checkbox(two way binding), changes state, my binded property gets updated and then I use the checked and uncheked events to trigger that action.The problem is that when I change the property in codebehind it also triggers those events and I do not want that. Right now, i am using a flag that enables, or not, the actions at the event handlers but I do not feel that this is a good idea.
Any sugestions or ideas?
I am considering using only one-way binding and control everything my self, using commands.
It looks like you have some confusion between your model and your controller. There shouldn't be any cases where it matters if the a change to the model comes from the user or not. If you want to have something like a confirm message it the user makes the change, then don't bind the view control directly to the model, but have the controller respond to the event.
That way, if the control is changed to be the same as the model, then the change is internal, and no confirm is required, but if the control is changed by the user, then the control state differs from the model, and a confirm can be shown.