Backbone.js Use View to Manipulate Another View - model-view-controller

My question is mostly conceptual about Backbone.js, but I can mock up some code if my question is unclear.
Consider a case where I have 2 sections on a website. A list of items as one view and another view that has a dropdown to select how the list of items should be sorted. Obviously, the list of items is associated with a collection of models that stores the actual data that populates the list. But I'm unsure the best approach for triggering the collection to be sorted differently when the other view's dropdown changes. Should I be changing the actual order of the collection, or just render the view in the order that I want in the view?
Also, is it a good idea to use a model for the dropdown to keep track of the state of the dropdown, and bind the list of items view to that model so that I know when to rerender the list of items?

You could take several roads here. Here's a few:
Use a router. The router would hold your views, or at least the top-level view (cleaner), and your dropdown view would trigger a route change, which would pass the information along to the view. Best if you want clean URLs.
Make a pointer to the list view in the dropdown view. When the dropdown view receives the change event, it explicitly tells the list view to update. (IMO a terrible approach, but listed here for completeness.)
Back everything with models. (Like you suggest in your last question.) The dropdown view would be backed by a model, and the list view could bind to that model's events. (Again, the list view still has to know about the dropdown model—not ideal.)
Make an event manager. When your dropdown recevies a change, you trigger 'sort' and anything that cares can listen to that event. This isn't a trivial solution but isn't overly complex either. Your list view could then register its intent to listen to the sort event with the event manager, thereby abstracting the actual view inside the event manager and away from the dropdown view.
1 & 4 are effectively the same thing, just depending on whether you want a router or not.
Basically my heuristic with these sorts of scenarios is "nothing should know about things it doesn't need to know about." Applied here, that means that your views shouldn't know about each other.

Related

How to add to an ObservableCollection from a different view?

(I'm using Prism Dryloc) My application consists of two views. The first contains a single list view displaying strings and the second - an entry and a button.
The listview is bound to an observable collection in the first page's View Model. How can I add to the observable collection from a different view?
Great question! You're essentially trying to pass data between views, and there's several ways of passing data between Views in Xamarin.Forms.
The two ways that seem relevant for your case:
Either making the ObservableCollection a public static object (so there's only one global instance of it). Not recommended.
The better way is to use the messaging center so that the second page publishes an event when the button is pressed, that the first page is subscribed to. And it passes that information that gets added to the list.
If these don't work, elaborate your use case and I'll suggest some more

Backbone Performance - Collection with a view per model or only one view for the whole collection

If a have a collection with 50 models, it seems that I have 2 main options to render a list displaying 50 models:
- Option1 : Create a specific "item view" for each model and append these views to a main "list view". This will provide a direct relationship between each "item view" and each model, will be practical and inline with Backbone philosophy
- Option2 : Have only one "list view" rendering the list with "data-attributes" helping to fetch the corresponding model when an event happens on a given list item.
I understand that option 1 leverages Backbone in a much better way however I am concerned with the number of event listeners with this option. If I have 4 events that I have to listen to per item, this will mean that I will have 4x50=200 events listeners on my list... vs. 4 (delegated) events listeners with option 2.
Given that I want to use Backbone for a cordova application, which option would be the most appropriate ?
Maybe in that case it would be practical to used a "mixed" approach. A View for every model, but event listeners only on the top list view which will then delegate them further. This reduces event listeners on DOM elements.
Despite that - I would only use per-item-views when you need that extra functionality such as rendering and handling an edit form, or when single items are likely to be changed so that they need to re-render often. If that isn't the case use a single list view and let it handle the events.

Cocoa bindings issue with three tableviews

im a osx-dev noob that is trying to build an application with three table views that will show the content of a core data store entity. But each table view is filtered on the attribute "status" of the entity.
the problem occurs when i also want to show the selected entity in textfields. I'm using three different array controllers with different fetch predicates. But in a textfield i can only bind the value to one array controller.
should i ditch the bindings and do it all programaticly or is there a simple solution to this? :)
here is an screenshot so you can grasp my app description.
Keep bindings to populate the text fields if it satisfies what you want to do with this GUI. I'd add an NSObjectController to control the one entity those fields represent. If you want the user's changes to those fields persisted, bindings are still awesome.
But I think with three tables that might control what's displayed in the text fields, you're going to need to have some sort of non-binding glue code that determines which of the tables wins. You can probably do everything you want by implementing some of the NSTableViewDelegate protocol.
If the text fields should display the last entity that the user clicked in any of the tables, simply have each table call the same tableViewSelectionDidChange delegate function. All three tables could have the same delegate. You can then call setContent on the NSObjectController from that function.
You could also use similar glue code to prevent more than one selection in any of the three tables, by having the same delegate function deselect everything in the other tables either through the view or the controller. But that's up to you and needs consideration of whether you want multiple selection, etc.

Using NSArrayController to bind model objects to an inspector view, how to catch special cases like empty and multiple selections?

I have inspector view and because it contains a lot of UI I want to explore cocoa bindings to connect it to the model. The inspector view will update depending on the currently selected object in an outline view and the inspector view displays controls to alter properties (like colour, name, shape etc.) that can be changed.
This works well when only one row in the outline view is selected because the view has a one-to-one relationship with the model object. However, there are two special cases that I want to be able to catch:
Empty selection
If no items in the outline view are selected I want to display a special "No items selected view" placeholder view.
Multiple selection
If multiple items are selected I can either display a "Multiple items selected view" placeholder view or I can decide to let the changes apply globally to all selected model objects.
My question is how can these special cases be caught when using bindings? Moreover, how can I do behaviour "A" when there is an empty selection and behaviour "B" when there is a multiple section. This sort of thing is trivial when using target/action because you can just code the logic into the action method.
Bindings seem great when propagating changes to values but I'm unsure how to go about implementing bindings that require different decisions based on current selection state.

Should navigation logic be in the controller or the view?

In an MVC web app, where is the "right" place to put the code/logic to display a url link to a "next page" navigation control, the controller or the view? If I put it in the view, I have to pass to the view not only the data to be displayed on the current page but also data relating to the next page aka the page id of the next page. If I put it in the controller, the controller has to be aware of the navigation that the particular view is going to display. Neither approach seems very elegant to me. Is there another way?
I don't know if there really is a "right" way to do this. Here's some different ways that I would think about it though:
if a page of items is itself an object in the system, then the controller makes sense
if a page only exists within the view logic, then the view makes sense
if the view receives the entire list, then pagination is a presentation concept
if you foresee the need for different page sizes or organizations, then keep the logic out of the controller
My gut says that you should try very hard to keep all of the pagination logic in the view. This usually means that you want some way to calculate what the next page is based on the current page in the view or make the controller have some concept of a starting point in the result set. I usually do the latter - the view retrieves the data with an optional starting point that is the ID of the last item on the previous page. This way the pagination logic is in the view and the data retrieval is simple.
One of the things to watch out for is how you will handle retrieving the next page of data if the item that you are keying on no longer exists. In other words, if you link says "the first page following item A" and "item A" has been deleted, then you need to do something reasonable.
The controller should provide meta information about the data being displayed: number of pages and current page index are two that get what you need here. The navigation control should encapsulate the logic which, given those two pieces of information, can render the rest.

Resources