How to pass data across screens using mvvmcross - xamarin

I have an mvvmcross xamarin project I am trying to figure out the best way I should approach sending data across screens for a particular situation.
My first screen is a search filter, it contains all kinds of criteria for the users to select for filtering results. The second screen is the results list screen.
I've seen numerous options for approaching this problem:
1) Use the Init method - The issue I'm having here is that when I pass custom objects, the values are always null/default. If I pass a string it works fine. If I could pass custom objects, I would either pass the EntityFilter or a List of Entities which is the results. I do have to query the entities on the filter page because what they select on one filter can affect others based on what entities remain. I have added the following to the AssemblyInfo.cs and it still doesn't work.
[assembly: InternalsVisibleTo("Cirrious.MvvmCross")]
2) Use Messaging. The problem here is that the result page isn't created when the filter is changed, so messaging won't work.
3) Use an in memory object. I created a results service that contains nothing but a public property of List of Entities. It's registered as lazy singleton in the IoC (as are all services). This method works and is my current solution. But it doesn't "feel" right. It feels like I'm doing something wrong or breaking best practices. Is this the way it should be done?

This is a fairly frequently asked question.
There's a recent question about using custom types for navigation at: Custom types in Navigation parameters in v3 - note that the original poster proposes one solution in their question there.
There are also several other questions around on this topic. The basic answer for all of these is that on many platforms navigation uses serialization techniques - e.g. Xaml Urls or Android Intents. Because of this, and because 'tombstoning' means that you can never be sure a "new" page will be in the same memory space as the "old" one, then by default MvvmCross insists on using simple serializable types for all ShowViewModel navigation.
This same reasoning for why navigation only allows simple serializable types is repeated all the way back to MvvmCross v1 - e.g. What is the best way to pass objects to "navigated to" viewmodel in MVVMCross?
The good news is that this topic is also getting some love in the official project docs - but these docs are still a bit of a work in progress - e.g. see https://github.com/MvvmCross/dev.mvvmcross.com/blob/master/_posts/1970-01-01-page-navigation.markdown

Related

Most correct way to pass dataobjects among ViewModels in Xamarin

I have a Xamarin.Form app, using Prism for MVVM, navigation, DI.
In a Page I download a dataobject from a WS, and I need to maintain it along with other dataobjects downloaded along the way (along with states, flags that doesn not really fit to be stored in Settings/Preferences), to be used in other pages of my application, so how can I pass it around?
I can collect all this data that must be used in various pages in a single "GlobalData" object, but what are the pros and cons of each possibile solution, of the following ones.
I excluded:
passing it as a NavigationParameter, because I see it as impractical to have to include the object each time I navigate to, I prefer the object to be available or instantiated everytime a page is created
I experimented with:
1 storing and retrieving from SQLite and LiteDB
2 storing and retrieving from MonkeyCache and Akavache
3 storing and retrieving from a global App object
4 injecting the object with Prism DI in each page
All the solutions work on my tests, starting from the easiest to implement, I would use 3, then 4, then 2, then 1.
Using a glboal App object is by far the easiest, I know the pros but what are the cons?
I just want to understand if there's something fundamentally wrong in each of the approach.
Thanks!
You missed the most obvious option - passing the data around during navigation.
INavigationService.NavigateAsync takes a parameter of type INavigationParameters which can store abitrary data. The same instance then shows up in the view model that's navigated to (if it implements INavigationAware).
I have found it useful to maintain singleton models for my view models to access. Some care needs to be taken to manage this data. I clear the data when it is not relevant. Since my workflow is fairly linear I populate it at key points in the workflow. Typically the models contain just DTOs and collections with initialization and clear methods.

How should I architect multiple instances of a View, all with very similar ViewModels using Prism and Unity

I'm using XamarinForms, and Prism for MVVM with Unity as my IoC container.
I'm refactoring a tonne of duplicate View and ViewModel code that a previous employee worked on. What they've done is essentially cut and paste a massively complex View and ViewModel. I needed to change some things in these, and had to do it 5 times because of this spaghetti code. This is basically what the view looks like:
The 5 instances of these CardViews and their different Viewmodels have a main title, 3 labels and 3 values that go with the labels. The values are retrieved using various restful calls (all using various parameters to retrieve them and processing the results of the calls too).
My question is, what patterns should I be using to simplify these 5 Views and ViewModels, preferably into only 1 file that I need to change? Roughly speaking, I think I should have a ViewModel that offers all of the text, values and functions that I require to get this remote data. But I'm scratching my head at all the different approaches that it seems are available to me (ViewModel interfaces, dependency injection, methods of registering the template view with different instances of the same ViewModel, etc).
What complicates my problem in particular is that these 5 different views are split across Prism Modules (i.e. .NET projects). I understand the need for these but they seem to just add to the problem of duplicate code that largely does the same thing. Maybe these should contain the logic for the restful calls and processing? But how would that fit in with my ViewModel/View association problem from above?
I will continue researching the best way to do this, but I just wanted to know if anyone can steer me into the best practice direction?
If you have five views that look the same and five view models that do (nearly) the same thing, drop four of each. To account for the differences in the view models perform, create services.
The BookService might implement GetTitles by querying a rest service for book titles while the DvdService queries another rest service for dvd titles. Both of them implement ITitleService. Then the UnifiedViewModel is specialized for books by passing it a BookService (preferably through constructor injection) and thus it does exactly what the BookViewModel did before. Just now you have one view model and five services where before you had five view models.

Pass and get attributes from one form but more than one entity for

Most of the article's talk about how to work with the forms like <form:form> Spring tags just with one bean(entity), but in my web app I have more then one bean(actually 3 of them, wich is mirror to my data model in DB(MySql)). What I want is to put values for all of the properties in my entities classes from one form(it may be a jsp or xhtml or html, whatever).
So, I'm kinda new in Spring MVC and as far as I know it has backing object which comes with <commandName> tag in <form:form> tag and I suppose to think that it may be just one commandName backing object for each form??
Q: - Could you please tell me how to easily(or direct me to any example's) to fulfil my pleasant headache.
Q: - It also may have something to get attributes in one controller class but by different methods. Do I have to store them in session or request? I'm thinking to have ModelAndView class for store multiple attributes in map and after store them in ModelAndView (in model). What you suggest?
hope you are having a wonderful day!
I'd suggest you investigate the technique detailed here:
http://forum.springsource.org/showthread.php?58993-Need-to-Populate-Form-data-into-multiple-java-beans
Also, I'm wondering if there could be a terminology issue here. Do you mean you actually want to have just one form on your UI, with a lot of inputs, or do you really mean you want it all on one SCREEN or page? I say that as its also possible to have multiple forms on one UI screen and go that route... which in fact might be easier, as you could then break up your processing into multiple controllers.
Another consideration on the above relates to screen design... if you are going to be populating the data for several beans from one screen, potentially that could be a LOT of data and your screen could get very cluttered and hard to read. So from that standpoint it might also be better to consider breaking your input controls up into multiple (related) screens. There is a little more about that at the bottom of the article I linked above.
You can refer: https://stackoverflow.com/a/4986410/1882833
One approach would be to have a seperate class which encapsules the required objects. And then use it as a command to set and get the data.

Generating Navigation for different user types, MVC, PHP

I have this idea of generating an array of user-links that will depend on user-roles.
The user can be a student or an admin.
What I have in mind is use a foreach loop to generate a list of links that is only available for certain users.
My problem is, I created a helper class called Navigation, but I am so certain that I MUST NOT hard-code the links in there, instead I want that helper class to just read an object sent from somewhere, and then will return the desired navigation array to a page.
Follow up questions, where do you think should i keep the links that will only be available for students, for admins. Should i just keep them in a text-file?
or if it is possible to create a controller that passes an array of links, for example
a method in nav_controller class -> studentLinks(){} that will send an array of links to the helper class, the the helper class will then send it to the view..
Sorry if I'm quite crazy at explaining. Do you have any related resources?
From your description it seems that you are building some education-related system. It would make sense to create implementation in such way, that you can later expand the project. Seems reasonable to expect addition of "lectors" as a role later.
Then again .. I am not sure how extensive your knowledge about MVC design pattern is.
That said, in this situation I would consider two ways to solve this:
View requests current user's status from model layer and, based on the response, requests additional data. Then view uses either admin or user templates and creates the response.
You can either hardcode the specific navigation items in the templates, from which you build the response, or the lit of available navigation items can be a part of the additional information that you requested from model layer.
The downside for this method is, that every time you need, when you need to add another group, you will have to rewrite some (if not all) view classes.
Wrap the structures from model layer in a containment object (the basis of implementation available in this post), which would let you restrict, what data is returned.
When using this approach, the views aways request all the available information from model layer, but some of it will return null, in which case the template would not be applied. To implement this, the list of available navigation items would have to be provided by model layer.
P.S. As you might have noticed from this description, view is not a template and model is not a class.
It really depends on what you're already using and the scale of your project. If you're using a db - stick it there. If you're using xml/json/yaml/whatever - store it in a file with corresponding format. If you have neither - hardcode it. What I mean - avoid using multiple technologies to store data. Also, if the links won't be updated frequently and the users won't be able to customize them I'd hardcode them. There's no point in creating something very complex for the sake of dynamics if the app will be mostly static.
Note that this question doesn't quite fit in stackoverflow. programmers.stackexchange.com would probably be a better fit

Using MVC, how should one handle communication between Views? Between Models?

Question number three in my quest to properly understand MVC before I implement it:
I have two cases in mind:
The primary application
window needs to launch the
preferences window. (One View
invoking another View.)
The primary Model for an application
needs to access a property
in the preferences Model. (One Model
accessing another Model.)
These questions are related in that they both involve communication across Model-View-Controller triplets, a topic that I haven't found much discussion of in my Googling.
The obvious way to fix this is to wrap everything in a top-level "application" object that handles transactions between Models and allows Controllers to invoke one another's methods. I have seen this implemented, but I'm not convinced its a good idea. I can also see possibilities involving Controllers observing more than one Model and responding to more than one View, but this seems like its going to become very cluttered and difficult to follow.
Suggestions on how best to implement this sort of cross-talk? I feel like its a very obvious question, but I've been unable to find a well-documented solution.
On a broader note, if anyone has a link that shows typical approaches to these sorts of MVC issues, I would love to see it. I haven't had much luck finding solid, non-trivial references. Examples in Python would be lovely, but I'll gladly read anything.
Edit 1:
I see some pretty interesting things being said below and in general no-one seems to have a problem with the approach I've described. It is already almost a lazy form of the FrontController design that Vincent is describing. I certainly don't foresee any problems in implementing that pattern, however, it doesn't seem that anyone has really addressed the question in regards to communication amongst Models. All the answers seem to be addressing communication among objects in a single Model. I'm more interested in maintaining separate Models for separate components of the application, so that I'm not stuffing fifty state properties into a single Model class. Should I be maintaining them as sub-Models instead?
With respect to (1), views don't invoke other views. They invoke controller actions that may result in other views being rendered. In your case, the primary application window contains a user interface element (button, link) that invokes a controller action to display the preferences window.
With respect to (3), model components certainly could be related to one another. This isn't unexpected nor to be avoided, necessarily. For instance your Customer model may have an associated set of Orders. It would be perfectly natural to access the customer's orders via a method in the Customer class.
You might want to take a look at the MVC page on wikipedia for an overview.
You may want to consider looking up the Front Controller design pattern.
The Front Controller pattern defines a single component that is responsible for processing application requests. A front controller centralizes functions such as view selection, security, and templating, and applies them consistently across all pages or views. Consequently, when the behavior of these functions need to change, only a small part of the application needs to be changed: the controller and its helper classes.
This way all requests from the view goes to the FrontController who then decides which specific action (controller) to invoke. Sometimes, it could forward straight to another view as in your first case.
There is no problem with multiple objects in the model talking to each other. In fact that will be very common. The way I see it, all the objects in the Model act like one component to represent the data and operations on the data.
This article might help. And this one.
Model does not mean a single model object. The model is the subset of the entirety of your domain model which is directly related to the controller actions and the views in question.

Resources