Mvvm pattern for windows phone app using StatusBar and MessageDialog - unit-testing

I have a windows phone app that uses the mvvm pattern. Current I am controlling the status bar and showing message dialogs from the ViewModel. So far I have 2 possible solutions:
make interfaces for the StatusBar and MessageDialog inject the instance:
public interface IMessageDialog
{
Task ShowMessage(string message);
}
public class MessageDialog: IMessageDialog
{
async Task ShowMessage(string message)
{
await new MessageDialog(message).ShowAsync();
}
}
//In the view model locator
SimpleIoc.Default.Register<IMessageDialog, MessageDialog>();
use a messenger and have the view handle it
Messenger.Default.Send<string>(Constants.ConnectionErrorDialog, Constants.UIMessages);
Please note that I am also using the ResourceLoader to get localized strings and I want to be able to unit test my app.
Thanks in advance

The general way of doing it, is via Dialog or Navigation Service (later one for Views/Windows/Pages obviously), which brings it to Option 1 for Dialogs
I am not familiar with the StatusBar thing, but if it can be declared in XAML, you can create and bind a ViewModel and then use an event aggregation (Messaging). Your StatusViewModel would bind its properties and register to the event aggregator, while your other ViewModel will send the events.
I wouldn't implement the event/message handling in the View's code behind, as this is isn't View logic and belongs to the ViewModel. Always use event aggregator/messaging to communicate between ViewModels, never for Views.

Related

Watchkit popToRootController not working

I am using a vertical page direction on my watch app, and I have a button that opens a new interface, which opens the third interface also from a button, this is done by using the modal view, and in the third interface i am calling popToRootController, because i want to go back to the first interface, but this is not working, have anyone same issue?
You need to use dismiss if you present view controllers modally using presentControllerWithName.
You can use popToRootController or popController if you present the view controllers hierarchically using pushControllerWithName.
You can read more on the Apple Interface Navigation guide.
In your example if you want to dismiss twice, you will have to pass a delegate or closure with the context to your second controller. Then you can call the delegate method or closure after dismiss() on the third controller. The implementation of the delegate method or closure will be another dismiss().

Popping consecutive view controllers and returning to main view controller (using navigation controller)

I'm following the Firebase-Chat-Messenger example in the "let's build that app" Youtube videos, and it works fine.
However, I'm testing integration inside a test application :
My test app has a menu with buttons and one of them is for the chat, which takes us to a similar interface (login menu and so on, anything beyond it is similar to the example in the tutorial. But you don't need to check it to answer my question).
Main menu button => Login/Register interface => Chat interface
I can't find a way to dismiss the chat interface to return to the main menu of the app, dismiss always returns to the login/register interface and sometimes causes errors. Could you suggest a good solution to use for this?
tl;dr : How to dismiss two or more views and return to main view (main menu) of app?
P.S : I'm new to Swift and still struggling with some basic elements, Sorry if the question seems too simple.
Use either popToRootViewController(animated:) to pop to the root view controller, or popToViewController(_:animated:) and provide the spicific controller you'd like to pop to.

Bind a class to dynamic service property

I have a service which I call state that just handles loading states and I can expand it to whatever I may want in the future. I needed this service so I could have different components talk to each other in a way so they would know if another component is loading or doing something.
Anyway I have this button that I use in different places that just sends an action, and then turns into a spinner until that action is complete.
They way the loading animation works currently is classNameBindings: ['state.working'],
However if I now have two of these buttons on screen at the same time, and I call this.state.set('working',true); all the buttons are now spinning.
I would rather pass in a property name to the button component that tells it what property to watch on the state service to determine if it should add the working class or not
I'm just having some trouble figuring out how to make this work in the component.
How can I have the class binding watch for a dynamic property name that will be passed to the component as something like loadingPropertyName so each button component can watch a different property for it's working class binding.
You can do something like this:
init() {
this.set('classNameBindings', 'state.'+this.get('stateProp'));
this._super();
}

MVC and co-dependent classes in c++

EDIT:
what I did instead was to move the "Main Window" creation and message handler into the controller, now only controller needs to know about Model and View. Since main window messages are processed in the controller itself, it can easily call view to change, and call model to do the logic, view never needs to call model, and if model needs to talk to View, then there are 3 options:
It can do so by returning a value to the calls from Model and then Model calls View according to what is returned from Model.
Model can post WM_APP messages to the main window and then Model calls View accordingly.
If the changes are very small, for instance, changing text of a static control, the Controller can pass handles to those controls to Model and Model can do the changes itself.
Any advices ?
I am trying to understand how MVC work in c++ and pure winapi, so am developing a demo app, and trying to implement my own interpretation/version of MVC.
The idea is to keep controller in total control, where everything is relayed through the controller.
Design :
Every class will be in it's own file .h and .cpp
Our main.cpp,view classes and model classes all will only be able to communicate to controller and controller only, there won't be any communication between then directly.
The view classes(there will be more then 1 gui(child windows) including the main window gui) will only create, show, hide, and destroy the windows(views) the messageloop of the main window and any sub or superclassesed child window will reside either in the controller folder or in the model folder.
Controller will further have sub folders with files views.h, views.cpp for communicating to view classes and model.h, model.cpp for communicating to model classes, similar in structure as in views.
Model will have files with different logics related to the application in different files.
It will look something like :
Problem :
There are too many co-dependent classes in different files.
What kind of approach would you suggest, I want to keep the idea of "Everything relaying through controller", if possible.
What's missing is some kind of abstract interfaces for the view and model to communicate. I.e., you rely on concrete types for communication.
This can be solved in a few different ways:
Abstract base classes as listeners/observers, (i.e. IModelListener, IViewListener) which the controller implements.
Events (i.e. ValueEnteredEvent from view and ValueChangedEvent from model).
Slots & signals ala Qt (or Boost), which allows a listener to connect to single output methods of an object.
The controller connects to the view and model object respectively, using whatever method you prefer. Hence, these do not know about the controller directly, they only talk to these given interfaces.
Avoid concrete dependencies & connections.
Abstract them away through interfaces (defined by the object it self)
Make sure each object knows as little as possible (but no less) in order to communicate effectively with it's peers.
I believe you can do this using pipes
The controller will have open pipes to the model class and the view class.
The view will have open pipes to the child view classes.
When a child view makes a change to the data, it sends the change to the main view through the pipe.
The view in turn sends the change to the controller through the pipe.
The controller updates the model by writing to the pipe.
The model updates the data and sends the refreshed data to the controller.
The controller sends the refreshed data to the main view.
The view then sends the refreshed data to the child views.
All communication is done by reading and writing to the respective pipes.
What I'm doing on MVC pattern is I create a ViewDelegate which is an abstract class. Make my controller inherited from ViewDelegate, and set controller as View's delegate.
Class ViewDelegate{
Public:
Virtual void onViewCallBack = 0;
}
Class controller : public ViewDelegate{
Public:
Static Controller* create();
Private:
Bool init();
Void onViewCallBack();
}
Class view {
Public:
static view* create();
Bool initWithDelegate(ViewDelegate*)
Private:
Bool init();
}
Use the delegate in View to call method declare in Controller.

How to make an action affect a sibling view without controller.get('view')?

Quick context:
Application view has 2 outlets. One for a toolbar. The other for the routable "main" view hierarchy.
app -- main
\-- toolbar
I need some buttons in the toolbar to trigger events in the "main" view. Not update any data in any model. I simply instruct it to trigger some changes to a drawing library that the view is presenting. Clearing the canvas, resetting zoom value and such.
In 1.0 pre2 and earlier I have used actions and router.get('someController.view') to get access to the view I want and trigger the action/method/event. Hardly the pinnacle of application design but it worked fine.
This option is now gone and I am at a loss for a good alternative. What mechanism should I use when communicating between views that are not in a child/parent hierarchy? Everything I have come up with is clunky and triggers my sense that "Ember has a better way".
In short I want:
A toolbar-button to trigger an event
The main view to react to this and perform some updates on parts of itself.
The main view to NOT re-render in the Ember sense of the word as would through routing. It uses a drawing library and integrating all it's properties and behavior into Ember models and controllers would not be a lot of fun.
The toolbar and the main view share a parent view but are on different "branches".
Poor Options I am considering:
The toolbar is very much an application level concern but it does have some buttons that need to instruct specific views. One option I see within Ember is to nest the toolbar under the "main" view. This seems wrong for some of it's other functions.
Communication could be handled by a controller (and possibly even a model) that would hold properties that the toolbar sets and the "listening" view reacts to and resets the value of. This sounds like abuse of the controller and model purposes and like a pretty poor event listener setup.
I could make the drawing library an application global as App.Drawing or something but that does also seems bad. It would also mean that the actions still would not be able to make use of any data in the view to update the drawing library with.
Any suggestions?
What mechanism should I use when communicating between views that are not in a child/parent hierarchy?
In a typical ember application this communication should happen between controllers. Otherwise "Poor Option 2" is on the right track:
Communication could be handled by a controller (and possibly even a model) that would hold properties that the toolbar sets and the "listening" view reacts to and resets the value of.
Consider using two controllers. Toolbar actions will target the ToolbarController, which is responsible for maintaining the toolbar's state and for changing main in response to user action. ToolbarController should declare a dependency on MainController via the needs property. For example:
App.ToolbarController = Ember.Controller.extend({
needs: ['main'],
buttonOneGotAllPressed: function() {
main = this.get('controllers.main');
main.turnOffAnOption();
main.makeSomeOtherChange();
}
});
Now MainController can be focused on the state of MainView. It should not be aware of ToolbarController or it's buttons.
This sounds like abuse of the controller and model purposes and like a pretty poor event listener setup.
Agreed it would likely be an abuse of model purposes but it is exactly what controllers are for.
This is definitely not an event-listener setup, but that does not seem a good fit in your case. The toolbar you describe seems to exist only to interact with the main view, so it makes sense to have a toolbar controller that depends on main and interacts with it directly.
If the components are truly decoupled then an observer (Pub/Sub) pattern might be more appropriate. See How to fire an event to Ember from another framework if that's of interest.