I have a collection of models in Backbone. One model is triggering a custom event, that I can catch, listening to the collection. What is the best way to find out, which model triggered the event?
You can add the model ID with your custom event like this:
yourModel.trigger('customEvent', yourModel.get('id'))
and on the callback that catch the custom event you'll get the id as a parameter:
yourCallback: function(id) {
...
}
Related
I have a nested composite view that checks its model for a collection, and if so sets that collection to itself as its collection.
onRender: ->
if model.attributes.has_collection
#collection = model.get 'myCollection'
This works quite well when the model has a collection, and the item view(s) all display, and when I add a new model to the collection, a new view appears.
However when there is no collection, and the button is clicked to create a new model, I need to create the model, set the collection (a collection of one) to the view's model, and get the view to display the model and any further models that are added. I have tried various things, right now I set the collection on the model and then run this function :
class List.myCompositeView
childView: myView
// *** //
setChildren: ->
#collection = #model.get 'myCollection'
#render()
The first model appears as it should, but further models that are created do not display. To repeat, they do appear when the collection is set in the onRender function. I realize there is lots of code that I did not add here, so if there is something (potentially) relevant to the problem that you need to know, let me know. Could it be that the view is not binding to the collection's events properly? Thanks!
A marionette collectionView has a private method called _initialEvents. When your collectionView is constructed it sets up this method to be called the first time the view is rendered. If your first render is when a collection view is not set then this would make sense that the events would not get wired up correctly. You should be able to call this private method after you set the collection and everything should work: #_initialEvents()
If it is helpful, this is the implementation of that method:
if (#collection) {
#listenTo(this.collection, 'add', #_onCollectionAdd);
#listenTo(this.collection, 'remove', #_onCollectionRemove);
#listenTo(this.collection, 'reset', #render);
if (#getOption('sort')) {
#listenTo(#collection, 'sort', #_sortViews);
}
}
We have written a base Backbone view class which abstracts the common methods and properties. All our view class in a module extends this base class. Also this classes use same model.
The model contains a collection. I am listening to change event of collection. Whenever there change in collection i want to listen for change event to the corresponding view. Instead this event is getting triggered for all the model instances created.
Please share your inputs to resolve this issue.
in your base view, you can listen to model change events like this
intialize: function(options){
....... init code
this.model.on('change',this.modelChanged, this);
}
then in the modelChanged handler you can trigger a custom event on the view
modelChanged: function(){
this.trigger('modelChanged', [your args]);
}
then you can listen to the custom view event with 'on' function like we did with the model
My viewmodel has two Collections, one is MainCollection and other is DerivedCollection. They are displayed using a control, so that when user interacts with the mouse, items can be added or removed from MainCollection, and DerivedCollection should be refreshed accordingly.
The first part (updating MainCollection) happens automatically via data-binding, but I don' know how can I hook RefreshDerivedCollection method to MainCollection.PropertyChanged event.
Both collections and the method live in the same viewmodel.
You can subscribe to MainCollection.CollectionChanged and refresh derived collection there:
MainCollection.CollectionChanged += this.OnMainCollectionChanged;
and
void OnMainCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// TODO: Handle main collection change here.
}
I have an ObservableCollection, this collection has 2 items (model), the model has Value as a property.
there is an event CollectionChanged for the collection, which suppose to fire when an item is changed, so I am expecting to see this event get fire when a model Value sets but I don't how model should be structured to fire that event?
I know that Model can have an event and when a Model is added a handler can be assigned to this event, but I want to know how CollectionChanged works for change of item in the collection?
CollectionChanged will only be raised when a model replaces another in your collection. Property changes to a model that is already inside the collection will not raise it.
You will need to handle those with the INotifyPropertyChanged.PropertyChanged event, which your models must expose.
It won't fire if a property within the element is changed, only if you assign a new "model" item to an index of the collection.
If you want WPF to update when you change a property value within your Model class, you need to make the model instances implement INotifyPropertyChanged.
A hack is to add a new element to the collection and remove it immediately. That will raise the collectionchanged event.
I have a XAML page whose DataContext is set to my ViewModel. A switch control on the page is bound to the following code in the ViewModel:
public bool TeamLiveTileEnabled
{
get
{
return Data.Subscriptions.Any(s => s.TeamName == this.Team.Name);
}
}
When this page is initialized, Data.Subscriptions is an empty list. I retrieve the list of subscriptions through an async web service call, so it comes back after the getter above is called.
When the web service call comes back, Data.Subscriptions has items added to it, and I'd like the UI to update based on the new result of the LINQ expression. Right now nothing happens, and I confirmed that Data.Subscriptions contains items that satisfy the condition above.
Data.Subscriptions is an ObservableCollection of Subscription items.
Can someone point me to what to do? Thanks!
The problem is that your ViewModel is not aware of any changes to the ObservableCollection. Within the ViewModel, subscribe to the CollectionChanged event of Data.Subscriptions.
Data.Subscriptions.CollectionChanged += SubscriptionsChangedHandler;
Within the event handler notify listeners of TeamLiveTileEnabled by sending a PropertyChanged notification
NotifyPropertyChanged( "TeamLiveTileEnabled" );