Can i have Multiple ViewModels being held in a ViewModel? - mvvm

I was wondering what your thoughts are on having a ViewModel containing a collection of other ViewModels.
For example if i have a stock price screen. In the MainView i want to be able to selct a stock ticker. When i press the ADD button on the MainView it should display a new stock price in the MainView.
My question is about how the add button should work?
Which of the two options should the Add button on the MainView do:
1) Pass the stock ticker (MSFT) to StockPriceService. The StockPriceService will retrive a StockPrice object. I can then pass the StockPrice object into a StockPriceViewModel. The MainViewModel will contain a collection of StockPriceViewModel.
2) pass the stock ticker(MSFT) into the StockPriceViewModel. The StockPriceViewModel will be implemented to call the StockPriceService and retrive the StockPrice object. The the StockPrice object will then be wrapped in the StockPriceViewModel.
Thanks,
CA

If the Add button is part of the MainView then it's events really should be handled by the MainViewModel and access to data for the StockPriceViewModel and thus StockPrice object, by the StockPrice related code.
The way to look at this is that you should still be able to display a StockPriceViewModel with populated data without recourse to any code in any other ViewModels, but in this case it is the MainViewModel that triggers the creation/instantiation of a new StockPriceViewModel etc.
So that would mean go with mostly method 2, say passing an initialisation value to the StockPriceViewModel constructor.

Related

Persist changes to core data item from SwiftUI view

I'm working on a SwiftUI app that is to display a number of entries from a Core Data database. Basically just about what the XCode template for such apps implements.
I've made two changes:
I put the code for the list item view into a separate file (BookmarkableItemView)
I added a property bookmarked to the item, which I called BookmarkableItem
The code in my view to show the list of items is now:
List(bookmarkableItems) { item in
BookmarkableItemView(item: item)
}
In BookmarkableItemView, the item property is an #ObservedObject.
Now, my BookmarkableItemView also contains a button that should toggle the bookmarked property on the item that the view represents. All fine and well - this is easy. But now I have to persist the changes...
I can think of the following two solutions:
Pass an action (simple a (BookmarkableItem) -> Void) to the BookmarkableItemView that's then called when button in the view is pressed
Have the view itself save the managed object context
The latter is a no-go in my opinion. The first solution works. There's now an bookmarkAction property in the BookmarkableItemView, so the above code looks like that:
List(bookmarkableItems) { item in
BookmarkableItemView(bookmarkAction: { toggleBookmark(item) }, item: item)
}
The action is called by the BookmarkableItemView and as a consequence, the toggleBookmark(_ item:) method is called.
But somehow I feel that I'm missing something about bindings in SwiftUI that would make the process easier? How can I have my parent view get a notification when a sub view performs changes to the data model so I can persist them?
onDisappear check if item.hasChanges
or use onChange on item.hasChanges

How to count element of one controller into another

i've a question to ask for my mvc project...
i have two controllers: Giurisprudenza e GiurisprudenzaNode, these controllers implement an index with the list of elements and a crud system to add/edit/remove elements. In the Girusiprudenza view page every element has a button that return you into the relative GiurisprudenzaNode page, with the list of elements contained into the primary element.
I would like to insert a label next to every element of the list in Giurisprudenza that say how many elements there are into that single primary element, but i don't know how to do that count... Anybody can help me?
for this you dont need two controllers or two different view .
For this you need to follow below steps.
Create a viewModel (Customize mix of both models)
add custom property in you this viewmodel for counts
create new view for this ViewModel class .
Let me know if you need code snippet for this.
View Model from MSDN

A master/slave panel in Extjs 5 MVC

I'm using Extjs5.1 powered by a MVC oriented code style.
I've got a main view which inherits from Ext.panel.Panel with a border layout.
On the east region, there's a grid with a store containing several records (or "models", I don't really know what terminology I should use here). (the "master grid")
On the center region, there is another view that inherits from a Ext.form.Panel and which is supposed to display the selected item of the grid . (the "slave form")
My goal is to refresh the "slave form" with the selected record of the "master grid".
The only way I found to "communicate" between the grid and the form is to execute a fireEvent('selectRecord', ...) from the main view controller and to listen to him inside the form view controller, but it seems odd as the form view is a child item of the main view.
Is there a more common way to do that?
By corrolary, is it a fine practice to make a view call functions of another view directly or should I make only their respective controllers interact?
What I usually do and I believe is the most common approach for this, is having a selectionchange event listener, that updates your form like this:
listeners : {
selectionchange: function(model, records) {
var rec = records[0];
if (rec) {
formpanel.getForm().loadRecord(rec);
}
}
}
for this to work, the name property of your form fields must match the name of the fields in the grid store model.
There is an example of this here: http://dev.sencha.com/extjs/5.1.0/examples/kitchensink/#form-grid

How to retrieve view from controller of another view?

I am just wondering how can I get one of the UI5 views in an application.
I know there is a method:
sap.ui.jsview(); // in case the view is written in JavaScript
But the problem with this method is: if you assign ID for any of the controls and you have already inflated this view, you get an error.
So I want to know how to check if the view already exists and then if yes return that existing view, otherwise create the view with the corresponding API such as the above one.
I also know in the control for view I can go
this.getView();
But as I said, how to get this view from another view?
I am not quite understanding your question
With managed object id's are unique, so if you try and create the same view twice you will get an error.
when you create your view the easiest way to access it is via an Id
sap.ui.jsview("view1",'testapp.view.view1');
sap.ui.getCore().byId('view1');
NB. views should not talk to anyone other than their controller A terrific Model View Controller (MVC) diagram
sap.ui.getCore().byId(<id_of_the_view>)
Where <id_of_the_view> can be obtained in the following way:
suppose that the corresponding controller of <id_of_the_view> is "controllerA.js",
then you can console.log, inside controllerA.js,
console.log(this.getView())
This will print you an object which contains the id of such view. This will be <id_of_the_view>
I think here is one solution.
Make a global variable;
Use it to create element.
In First View:
var mytextField ;(use it as global)
mytextField = new sap.ui.commons.TextField('textfieldId');
In Second View:
var myValue = mytextField .getValue();
~Mansi Rao

Passing data from one view controller to another without using Segue

I have a UITableView (let’s say class “Parent” which is in view "screen 1"). When I click on one of the Parent’s cell's, I’m displaying another UITableView (let’s call it class “child” in view “Screen2”). Parent and child are connected through “segue” and I’m able to pass the data using “segue”.
For example, parent is having cell – “Cell1” and on touch “Cell1”, I’m getting “Cell11”,”Cell12”,”Cell13” [this is “screen2, table view object”].
Now, there are some descriptions associated with “Cell11” (Once I touched “Cell11”) and i'd like it to display Cell11’s description in another view controller (“screen3”). Here, to pass information between “screen2” to “screen3” I'd rather not to use a “Segue”.
How can I do this?
There are two ways in which you can present a new screen.
1) with the interface builder, here you use a segue to pass something onto the new screen.
2) manually instantiating it, after it is instantiated you can just present it.
Considering you do not want to use method 1, you can use method two like this:
ScreenBClass *screenB = [self.storyboard instantiateViewControllerWithIdentifier:#"screenB"];
screenB.objectPointerInOtherClass = self.objectIWantToPass;
[self screenB animated:YES];