Backbone.js: How to get the index of a model in a Backbone Collection? - backbone.js

Is there a way to find the index of a model within a collection?
Let's say in a view we have a model we're working on, could that model spit out it's index within the collection it's currently inside of? I'd like to do this because I want to access the model above or below the current target.
In other words is there something like:
index = this.model.index
modelAbove = this.collection.at( index-1 )
My data is a nested set so I can just do a search on the "lft" or "rgt" columns, but I didn't want to reinvent the wheel if Backbone already has this info available.

yes, backbone provides access to many underscore.js methods on models and collections, including an indexOf method on collections. it also provides an at method like you've shown.
var index = this.collection.indexOf(this.model);
var modelAbove = this.collection.at(index-1);

Related

How to correlate view order (using orderBy) with model order

I have an obviously simple but yet challenging problem in my AngularJS app:
When using orderBy on the view I loose the correlation between the order of the related model and the view order.
What I want to do: My view is a table. I want to set a highlight class for the selected row and I want to use cursor up/down keys to move this highlight.
I tried to decouple $index from the tracking by using track by currentDocument.objectid, but that doesn't seem to work.
How can I correlate the currently highlighted row in the view with the currently highlighted element of the related model in a way that I can use -1 or +1 with the cursor keys?
As the order of the data is important to your business process, it makes sense to make the order part of your actual model. If you read the last example of orderby on the angular api (https://docs.angularjs.org/api/ng/filter/orderBy), you will notice they achieve this very thing. Basically, instead of binding orderby directly to some model value, create your own order function and manually order your model.
I have created a plunker here: http://plnkr.co/edit/oM97ZTAIHTjI6YFiGDwI?p=preview Just click on the persons name to see the example (and reorder the list and try again).
Basically you create a manual sort function like this:
$scope.order = function(predicate, reverse) {
$scope.friends = orderBy($scope.friends, predicate, reverse);
};
Which actually reorders the model itself, rather than just the view array. You can call it however you like. Then you can simply pass $index from the view, and it will correlate correctly to the view order.

Sorting and Filtering a collection in a Paged ListBox

I have a database with 10,000 items, to which you can add and remove while the app is running.
I have a ListBox that displays at most 100 items, and supports paging.
You can filter and sort on the 10,000 items, which needs to be immediately reflected in the listbox.
I have a button that randomly selects an item as long as it passes the filters.
What is the best set of collections/views to use for this kind of operation?
So far, my first step will be to create an ObservableCollection of ALL items in the database which we will call MainOC.
Then create a List of all items that match the filter by parsing MainOC which we will call FilteredList.
Then create a ListCollectionView based on the above List that holds the first 100 items.
CONS:
You have to recreate the ListCollectionView every time a sort operation is applied.
You have to recreate the ListCollectionView every time you page.
You have to recreate the ListCollectionView every time a filter is changed.
You have to recreate the ListCollectionView every time an item is added or removed to MainOC.
Is there a better approach that I am missing?
For example, I see that you can apply filters to a ListCollectionView. Should I populate my ListCollectionView with all 10,000 items? But then how can I limit how many items my ListBox is displaying?
Should I be doing my filtering and sorting directly against the database? I could build FilteredList directly off the database and create my ListCollectionView based off that, but this still has all the cons listed above.
Looking for any input you can provide!
This is a problem which is easily solved using DynamicData . Dynamic data is based on rx so if you are not familiar with the wonderful Rx I suggest you start learning it. There is quite a bit of a learning curve but but the rewards are huge.
Anyway back to my answer, the starting point of dynamic data is to get some data into a cache which is constructed with a key as follows
var myCache = new SourceCache<MyObject, MyId>(myobject=>myobject.Id)
Obviously being a cache there are methods to add, update and remove so I will not show those here.
Dynamic data provides a load of extensions and some controllers to dynamically interrogate the data. For paging we need a few elements to solve this problem
//this is an extension of observable collection optimised for dynamic data
var collection = new ObservableCollectionExtended<MyObject>();
//these controllers enable dynamically changing filter, sort and page
var pageController = new PageController();
var filterController = new FilterController<T>();
var sortController = new SortController<T>();
Create a stream of data using these controllers and bind the result to the collection like this.
var mySubscription = myCache.Connect()
.Filter(filterController)
.Sort(sortController)
.Page(pageController)
.ObserveOnDispatcher() //ensure we are on the UI thread
.Bind(collection)
.Subscribe() //nothing happens until we subscribe.
At any time you can change the parameters of the controllers to filter, sort, page and bind the data like follows
//to change page
pageController.Change(new PageRequest(1,100));
//to change filter
filterController.Change(myobject=> //return a predicate);
//to change sort
sortController .Change( //return an IComparable<>);
And as if by magic the observable collection will self-maintain when any of the controller parameters change or when any of the data changes.
The only thing you now have to consider is the code you need for loading the database data into the cache.
In the near future I will create a working example of this functionality.
For more info on dynamic data see
Dynamic data on Github
Wpf demo app

Fetch models in backbone collection creation

I have a model and collection, when I create my collection I would like to fetch three models instead of all collections.
If I use collection.fetch() - if will fetch all objects, right now - I am fetching each model and then creating the collection, like this -
var model = new App.Model({ Id: 1 });
model.fetch().success(function() {
var collection = new Collection(model);
});
(This is a simplistic version for one model, if I want to fetch multiple, I use $.when)
There is an official/better way for doing this? or I am at the good path?
I think you can get the models that you want from the original collection and put them in a temp collection. So you can fetch the temp collection once instead fetch each model one by one.
After a little bit of thinking, I saw that my collections have many to one relation to my model.
So I used backbone-relational to fetch all of this collections.

Are collections required?

Sorry this is a noob question but if I only need some initial data when the application first loads is a collection always needed or can the model fetch the data and pass it directly to the view?
Nothing in backbone is really "required". It's a very thin, more-than-one-way-to-do-it framework. Jeremy recommends data that can be bootstrapped in the initial page load be handled that way, so your HTML could include you initial data as JSON in a <script> tag. You can pass that JSON to a Backbone.Collection (if it's a list of similar records) or a new Backbone.Model (if it's a single domain object). You can also just use a model and call model.fetch to get your initial data. Model vs. Collection is more about single domain object with name/value pairs vs list of many objects where iterating, sorting, filtering are common.

cakephp: abstract classes, factory, return objects

I would need an idea or two how I would do this in cakephp (using latest version)
I am building a web based game where you will be able to collect Items
Without a framework I would have an abstract base item class that every item would extend to
And when displaying for example a inventory i would factory all items the user currently have and then return a object for each item.
classes...
BaseItem
WeaponItem
HealingItem
etc..
How would I do this in cakephp? Would I go for a model for each item class ... and how would i factor to get the object? ...
Assuming you're using a database as the data store, presumably you will use a single table for all items the player can collect? If so, you probably want a single Model class.
It's possible to have an inheritance hierarchy for models in CakePHP if you want. But you can often achieve sharing of Model logic using a Behaviour.

Resources