Deactivate composed viewmodel - durandal-2.0

There is a lot of questions about this but I cannot find any answer that works with the latest durandal version (2.1.0).
I am showing a child viewmodel inside my page using this:
<div data-bind="compose: { model: activeScreen, activationData: {id:selectedId}}"></div>
activeScreen is an observable to which I pass an string like this: viewmodels/child
It works, and the child viewmodel gets activated and shown on the screen. But when I change activeScreen, I need the child viewmodel to run deactivate. Is it possible? How?

So long as your child views are instance modules and not singleton modules, you can move that code to the detached handler. That's what we do as well: All of our child views are managed through dynamic composition, not child routing (which just doesn't work for the enterprise-style app). The deactivate handler comes into play in the context of routing.
By dynamic composition I'm referring to the swapping in and out of child views/viewModels through an observable.
But, again, the key to making this work is that the child views must be instance modules. That way they'll actually get unloaded from memory. If you go with singletons, the modules will never get detached (although there are ways to force this to happen).

Related

How the parent View-Model will gain access to the child View-Model?

<Page x:Class="ParentView">
<view:ChildView/>
<view:ChildView/>
...
</Page>
Prism attaching the child View-Models as AutowireViewModel=True. How can I gain access from ParentViewModel to the child View-Models ? (They are actually fabricated in one factory delegate that configured in the IoC container.)
protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved);
method isn't available in Page control, which could have been invoked upon a UIElement is added ?
How can I gain access from ParentViewModel to the child View-Models ?
The easiest way is to go the other way round: make the parent view model create the child view models, expose them as a collection-valued property, bind that to an items control and map the items to views through data templates. Everything else is unnecessarily complex and more or less hacky.
Use AutowireViewModel=true where it makes sense (i.e. if you want to use Prism's navigation), not everywhere just because you can.

Show specific presenter instance to flex panel gwt mvp

I'm still learning GWT, yet already have to face some kind of challenge for a work I have to do. Can't show any specific code so I'll try to explain it well.
Here's the situation: A certain class "Navigator" creates and save the Presenter instances of my architecture to allow reusing them. There is a method show() inside that same class that actually displays the view related but that system only works full screen by calling RootPanel.get().
What i'd like to do is showing that presenter instance's view inside of a flex panel element declared in a class myView (related to a class myPresenter) that basically uses Flex Panel to structure it's content.
To make it maybe more clear:
class myView{
...
flexPanel.setWidget(firstWIdget)
flexPanel.setWidget(secondWidget) //secondWidget to be replaced by a "thirdWidget"
...
}
I'd like the secondWidget to be replaced by another one, let's call it thirdWidget, that consists of a specific presenter instance's view.
To resume, I'd like my presenter instance's view to not go full screen but only occupy a certain area of the screen.
The displaying is managed almost entirely programmatically, means very limited use of css files and no use at all of xml ui files.
How can I manage this ?
Thanks
Use a SimplePanel as a container for your views returned by your Navigation class instead of adding them directly to root panel, and use that instance of SimplePanel where ever you want.

Is there any reason to use target="view" or target="controller" in Ember actions?

I'm playing with actions in Ember and I see that some people use targets that point to their controllers or their views like such:
{{action saveNote target="view"}
However, I also see that Ember supports event bubbling much like the DOM, in that events will work their way up to the application controller and router.
Is there a reason for specifying either "view" or "controller"? If I understand it correctly, the view/controller that the template's action belongs to will be the first in line to receive the event, so why specify it?
There's really no reason to target the controller, since it's the default target. Events not handled by the controller will bubble up from the controller to the routes.
However, if you want the view to respond to an action, you'll need to target it explicitly.
target="controller' is not needed ( anymore? )
target="view" can have many uses which are perhaps local to a specific view instead of belonging into a controller. Like toggling the display of an item.
But target also has other use cases like if you want to target a controller you have declared in needs which is then accessible in controllers.<nameOfController>

Ember.js recursive controllers and views

Say I have a list of Action objects, which corresponds to a Ember model. Each has a few properties (timestamps) and a detail attribute, which can can recursively contain more details (arbitrarily deep nesting). You can think of the details as nested lists.
I want to write a UI that allows easy editing (auto completion of values, easy copy and paste, reorder elements, etc) of the detail for any Action object.
Right now, my DetailView template will recursively render additional DetailViews:
{{#if view.content.hasChildren}}
{{#each child in view.content.children}}
{{#DetailView contentBinding=child}}
{{/each}}
{{#else}}
{{#EditDetailView contentBinding=view.content.value}}
{{/if}}
So each DetailsView corresponds to a node in the Details object tree.
But I am unclear how to add controllers to the mix -- there is additional state I need to store / functionality to implement (e.g., transforming values from the Detail object for display in the DetailsView; handling events for inserting/deleting/reordering elements; changing the structure of the Details tree) that belongs neither in the model nor the view.
Ideally I would have a DetailsController serving as a proxy a Details per DetailsView. Can I dynamically instantiate controllers and set up their contents within a view template? My understanding of the new Ember Router is to setup controllers and outlets in in a given route; however, that doesn't seem to apply here because no routing is being done at all. All suggestions / insight about how to handle recursive controllers / views / routes welcome.
I've taken a look at EmberJS Nested Views and Controllers, but that proposes I have a single ArrayController for all Details, even across Actions ... this would not preserve the tree structure of the nested details either.
I've also looked at Recursive view in handlebars template not working after upgrading to Ember 0.9.6 but the solution doesn't say anything about controllers.
** UPDATE Feb 20, 2013 **
API documentation for the {{control}} helper is now available here. It warns that "The control helper is currently under development and is considered experimental."
To enable it, set ENV.EXPERIMENTAL_CONTROL_HELPER = true before requiring Ember.
** UPDATE Feb 3, 2013 **
A new helper {{control}} has been added to ember, implementing the Reusable Views proposal. So to have a DetailsController proxy a Details per DetailsView you can just:
{{control 'detail' child}}
See the {{control}} tests for example
Ideally I would have a DetailsController serving as a proxy a Details per DetailsView. Can I dynamically instantiate controllers and set up their contents within a view template?
Typically the way to do this would be via the handlebars {{render}} helper, which renders a template with an appropriate view and controller. Unfortunately you cannot use {{render}} to insert the same template more than once, so it cannot be used within an {{each}} block.
There was a lengthy discussion on the topic recently. See: Non-Singleton Controller Discussion!
Two solutions were proposed. The first involves adding an itemControllerClass property to ArrayController. If this property was set, the ArrayController would automatically wrap new contents in the specified class. This was added to ember a few weeks ago and takes care of most use cases, where you have a flat-list of items and want each to be wrapped in a proxy.
The second proposal, Reusable Views, allows you to provide a controller class to a view.
{{view UI.Calendar dateBinding="post.startDate" controllerClass="App.CalendarController"}}
This would create an instance of App.CalendarController for each UI.Calendar widget, which would be tied to the lifecycle of the widget. As of today this has not been implemented. See {{view}} should have an option to create a controller! for the latest status.
So AFAIK there is not a good way to accomplish this for the use case you outlined. Meantime, binding data to the view:
{{view App.DetailView contentBinding="child"}}
and then having some logic in the view itself seems reasonable. If/when Reusable View support is added to master you can pull that logic up into the controller.
See: https://github.com/emberjs/ember.js/issues/1766

ember js subviews and didinsertelement event

I'm writing an Ember.View, which turns a tree structure into a menu. I need recursion for this, so what I use in my view template is a {{view}} helper, which recursively calls itself to build a nested <ul><li> structure.
What I need is a hook to call some jQuery plugin to turn this structure into the menu. When I call the plugin from the didInsertElement event, the subviews haven't rendered yet. How can I run code when all subviews have finished rendering?
Try calling the plugin within Ember.run.next() which should call it after the current run loop is complete... which I believe won't happen until all of the subviews are created.
Docs -> http://docs.emberjs.com/symbols/Ember.run.html
This might help in your situation, I made a handlebars helper that tells you when the sub-section has rendered. By default it sends an event to your view object, so each of your instantiated views would receive an event whenever they rendered.

Resources