How to send data from one view to another which are on different urls?
A little bit strange question, but OK, let's try to imagine your problem in complex and give an answer.
Imagine application for reading books (like iBooks in web). We have one parent View called ApplicationView which creates several children views and some of them are BookshelfView (available on #bookshelf url) and BookView (available on #book/:id url).
Now, you mark your book as unread from your BookView and you know that your BookshelfView should change the appearance of this book. OK, it is not "moving data from one view to another". You just change the state of your model and your views catch this "change" event and update their html.
Let's describe more complicated situation. Imagine the same application. But at this time you decide to switch portrait orientation to landscape orientation. You make it in one view and you want this change to affect other application views. This can be done in several ways:
Views should stay loosely coupled you should use some kind of mediator pattern.
From Backbone 0.9.9 you can use global Backbone object as Mediator, as Backbone supports Events interface
You can create and additional model for Mediation between two or more views but there is more beautiful solution:
If you have one parent view for several child views you already have that mediator. Just send events to parent view from one view and listen to that events on parent from other view.
I also recommend you check this question
Related
or should I just create one view for each model ? I mean with backbone alone I was doing some kind of "renderSubview" , with marionette this is pointless and I just shoudl avoid this ?
Is it bad to bind a marionette view to several model ? (and update different part of its template according to multiple models update ?)
thansk a lot
Marionette doesn't give you any tools to do exactly that, but it's a thin layer on top of Backbone; the approach you describe will work just fine.
However, if your sub-views are not very simple, it's probably better to use a Marionette LayoutView. That way you'll benefit from encapsulation and DOM isolation (so sub-views won't interfere with each others' events).
Simple sub-views, Backbone-style
This approach is good for trivial subviews - probably with very simple templates and little user interaction. You don't need anything more than the approach you described:
You can add renderSubViewX methods to any Marionette view type (or even a vanilla Backbone.View). They'll look like typical Backbone render methods - call a template function or create some DOM nodes and insert them into the document. Use this.listenTo(this.model1, "change", this.renderSubView1, this) to re-render on changes.
LayoutView
If the sub-views are more complex (perhaps they allow non-trivial user interaction) you will benefit from creating a separate ItemView for each model. Use a Marionette LayoutView for the parent view.
Derick Bailey's blog post on Layouts is a little out-of-date but provides a good overall introduction.
Pretty cryptic question I admit.
I'm looking for references / best practice in updating views based on a GUI event.
Basically I'm seeing 2 different ways to do this:
every view-change is a reaction to a model-change
Gui event
viewhandler (custom or 2-way binding lib) that
updates Model based on view
the View has a listenTo defined on the MOdel that was updated, which gets invoked
do whatever DOM-changes we want
Do DOM-changes directly in the viewhandler
Gui event
viewhandler (custom or 2-way binding lib) that
updates Model based on view
do whatever DOM-changes we want
the View has a listenTo defined on the MOdel that was updated, which gets invoked
The fist approach seems the most clean to me: it can use validation rules on the model, before changing the DOM and the flow just feels better. However, I can't find any good references to back this up. What is generally considered best practice here?
I wouldn't know what is Overall Internet Agreement on that topic, but working on a fairly large Backbone application with complex views, the first approach is what has proven the most maintainable.
One way to see it is that as you know, Backbone's Views and Backbone's Routers are kinda sharing the workload of what would be an actual Controller in a standard MVC (say, Rails). What that means is that in a view, you'll typically have the logic to translate GUI events (click on X) to Model Change (do Y) and the logic to translate Model Changes (new state after Y) into DOM changes. That doesn't mean the logic needs to be in the same place, those are two separate things. Your model may be shared among multiple views and you need your View to react regardless of where the change is originating. You could also be waiting for the server to answer whatever, and so, the DOM update would be in a callback anyway.
A pattern I have been using a lot lately is to have a _renderUpdating() to update the DOM to let the user know that his action has been taking into account (add a spinner near to whatever triggered the change), but I let events do the actual re-rendering once the server has returned the new model.
There is nothing that prevents you from going with the 2nd approach in simple cases, but as your application grow, you'll be very happy to have more than just a single render() that erases everything (including subviews) and you'll be looking at having a clean break between view -> model (which is the role of a controller) and model -> view to allow for more flexibility.
I am working on a UI, using Backbone + Marionette.js, which displays the same Widget multiple times on a single page. I am struggling with whats the best way to contain events inside each widget. Lets say each widget displays a selected friend's Facebook information (interests, status feed, mutual friends). If the user changes the selected friend for that specific widget what would be the best way to update the models that are part of that widget?
Here is how I am thinking of solving this ...
Create Setting Model - when user selects a different friend inside a widget the Friend select view updates the Setting model.
Approach 1:
Controller listens to the setting model on "change" events and in turn updates all the relevant models. Each model will never know of the setting model.
Approach 2:
Pass setting model to each Model's options and each model listen's to the setting model and when it changes it does whatever it needs to (reload, etc).
These are the 2 approaches that come to my mind. I feel like I am liking the Approach 1 better, but I would appreciate any feedback from people that have used Backbone in a similar fashion.
Thanks,
Habeel
I would go for approach 2 using a singleton setting model as you suggested. That way the views or models listening to the settings are responsible for doing the updating. Approach 1 has two potential pitfalls. If you move the logic of what actually happens to the controller, it can become convoluted and complex. If the controller just reacts to change events on the settings model and propagate them to other models and views, then there seem to be little reason for it to exist.
Another approach could be to make use of Marionette's event aggregator feature. This would allow you to not even need a settings model. Instead, just have the changed model fire a global event that the other models are listening for and adjust accordingly.
I've inherited an application which uses the view-first MVVMC patern
In the application I've created 2 step process which creates a person and assigns them to a group. To do this I've created a view and corresponding view model (all views have a 1-2-1 relationship with a view model, view models are injected into the View constructor and are registered with the Unity container using the TransientLifetimeManager) called CreatePersonMaster, the view simply contains a region (shown by the dashed line) which sub-views can be loaded into and the view model subscribes to two loosely coupled events, "PersonCreated" and "GroupSelected". The "PersonCreated" event saves a Person entity in a field and the "GroupSelected" event takes the saved Person, creates a Group association and saves them to a database.
This view/view model doesn't do anything until the events get raised so I load the following sub views into my the region.
These views/view models fire the events which get handled by the master view.
I also have an edit view where I want to re-use the select group view.
I can do this by subscribing to the appropriate events in the EditPersonMaster view model.
My question really is, is this the appropriate way to do this? Because I'm using loosely coupled events I don't get any feedback into the sub-View/ViewModels if there's an error when creating/reassigning? I could probably fire another "ErrorBlah" event for the inner view/model to handle and update the view.
Is there another way to do this? Composite commands don't seem to fit the bill but maybe I don't understand them correctly.
Here is how I understood your question: You have persons stored in a database, which have a property/column group. In your UI, you want to create persons and assign the group property. Also, you want to be able to edit the group property of existing persons in a different region/page/master. You want to reuse the control for assigning the group. Your controls fire an event, which is handled by the Master in a way that it creates the entries in the database (is that correct?). Your question is whether this is a good approach and what alternatives you have?
I see two options:
1. Modularize your business logic:
You could inject a data service into your ViewModels, which could access the database directly. This way you can handle errors etc.. directly where they occur and don't have to pass them through the whole system. If you want to notify other modules of changes on the database (specifying the changed dataset or so), you can do so with a composite event. I think of the PRISM modules more as of complete elements, including UI and business logic and keep communication between them as little as possible.
2. Keep your business logic central and share it:
If you want to stick to your architecture, have singleton Model which is injected into the ViewModels. Manage your state in the model and have the ViewModels pick the pieces they want to provide to their view.
Hope I got he point, though...
.
Hello guys,
Consider the usual scenario of Prism (WPF/Silverlight) in which we've multiple regions, and in each goes a view (XAML), so a situation might arise when we interact with one view (XAML), either using mouse, or keyboard, we may want to change or update other views (which happen to be different XAMLs) accordingly. For example, on selecting an item from a view, say ItemPanelView, we may want to show the details of the selected item in other view, say ItemDetailsView.
So my question is,
Would it be a good idea to bind elements from one view (XAML), to the elements in the other views (different XAMLs), to implement such functionalities? If I'm not wrong, using this approach we would not need to go from one presenter to other (using TwoWay bindings etc), so as to update the view in other region.
Or, is there any elegant yet simple way to do this?
.
I suggest you take a look at the Prism's EventAggregator (http://blogs.msdn.com/b/francischeung/archive/2008/06/02/decoupled-communication-with-prism-event-aggregation.aspx). Each of your views (or preferably view models to which views can respond/update using triggers) can subscribe to / publish a shared event. However, I suggest that instead of simply responding to a mouse click or keyboard event to raise this shared event, make the shared event meaningful (i.e. MyItemSelected or MyItemHidden). If you need more assistance or clarification with this, let me know.
There are several ways to do that without breaking canonical concept of the PRiSM.
As [MSDN docs][1] (Chapter 9: Communicating Between Loosely Coupled Components) tell us:
When communicating between modules, it is important that you know the differences between the approaches so that you can best determine which approach to use in your particular scenario. The Prism Library provides the following communication approaches:
Commanding. Use when there is an expectation of immediate action from the user interaction.
Event aggregation. For communication across view models, presenters, or controllers when there is not a direct action-reaction expectation.
Region context. Use this to provide contextual information between the host and views in the host's region. This approach is somewhat similar to the DataContext, but it does not rely on it.
Shared services. Callers can call a method on the service which raises an event to the receiver of the message. Use this if none of the preceding is applicable.
In your case you should use EventAggregator or RegionContext. Shared ViewModel is possible but this is the last resort.