Problem when passing a singleton to another viewmodel using self.VM.Navigate - mdriven

In the public part of my app the user starts with a link to a VM (IndexBookingPage) with DVM params. An action looks up the publicbookingpage object from Id, and if found navigate to Eventlist. This part works. But in the Eventlist self is null. Why?
IndexBookingPage
EventList

Don't set self inside a viewmodel.
Instead, use OneSession.oclSingleton by itself. Use a let statement if you think it's too bulky in text to repeat OneSession.oclSingleton.
Why do you have "Requires root" on the IndexBookingPage at all?

I have change to OneSession.oclSingleton instead, and now it works. Is there a rule when to use self or Class.oclSingleton?
I just tried different solutions, thats why I checked required root.

Related

How to call a Mojolicious controller method after failing on template

I have a Mojolicious problem that I suspect has an easy solution, but I can't swim through all of its code.
$r->get(
'/:controller/:action',
sub {
my $c = shift;
$c->render_maybe && return;
# No template. Either call controller->action() or dispatch as POST
}
);
$r->post('/:controller/:action');
As you can see, I have two routes that use the same URL, one for GET and one for POST. The POST is straightforward. It renders after finding the controller and action method and isn't concerned with a template. I have the GET method working where a template exists, ignoring the controller, by using a callback with render_maybe(). My issue is, if there isn't a template, I want to go ahead and run the controller's method.
One solution would be to simply identify my controller and call the action. Since I'm using placeholders in my route, I can't simply hard code this. So, is there a Mojolicious way of getting my controller class, or actual code that will get the class and call the method? I have both controller and action defined in stash, so this really shouldn't be a big deal. Mojo knows how to do this internally.
Another option would be to convert this to a POST method and run it as normal. I don't know if it's best to either come up with the URL, or find the defined POST route, or just convert my GET to a POST. I'm not sure how to accomplish any of these.
Thanks.
I'm not sure if this is the intended use case for under(), but it seems to be a decent solution to my problem.
$r->under( '/:controller/:action', sub { !shift->render_maybe } )->get('/');
$r->post('/:controller/:action');
Chaining under()->get() will create a nested route. The first in the stack will render a template, if it exists, from the render_maybe, stopping there. If the template doesn't exist, it will go to the standard get(), which will first check for a controller action. This is exactly what I was wanting.

Command class in Caliburn Micro

On my first project trying out Caliburn.Micro, I like a lot of the things :-)
One thing I miss (or havn't discovered yet) is how to separate the viewmodel and a command.
CM doesn't support ICommand, as it's way of doing things is superior. I'm sure it's true, so I would love a small push in the right direction to achieve this or perhaps discover a better way.
As I understand you have to put the "Execute" method and "CanExecute" property directly in the viewmodel, named to match the control in the view, to get the magic to work.
I would like to put the "Execute" and "CanExecute" in a different object that is property on the viewmodel and then CM would automatically bind to that object, using the control name and property names as usually.
Repost from the forum on Caliburn Micro, I didn't get any answers so I'm trying my luck here.
You should try to avoid invalidating the Law of Demeter. Therefore, on your view model you can have an execute method, and a CanExecute property (usually calculated), and these can call into the containing model where appropriate, e.g:
public void Save
{
// .. save logic
}
public bool CanSave
{
get
{
return this.model.CanSave ... and other logic etc.
}
}
You must remember to notify a change in the calculated property when the can save state changes, e.g:
public void CodeThatGetsRunWhenAPropertyOfTheModelChanges()
{
this.NotifyOfPropertyChanged(() => this.CanSave);
}
If you have e.g. a Button on your view with x:Name="Save", then Caliburn.Micro will automatically invoke your Save verb on the view model when the button is clicked, and will automatically enable and disable the button when the CanSave property value changes.
To avoid fat ViewModels you also need to avoid fat Views. Caliburn.Micro allows you to compose Views/ViewModels as described in Screens, Conductors and Composition.
The short version is, you can include a "DetailView" and "DetailViewModel" pair in a "MasterView"/"MasterViewModel" shell by defining a DetailViewModel-typed property in MasterViewModel and adding a ContentControl named after it in MasterView. Binding and actions work as usual, so you avoid both fat models/views and routing of commands.
Another option is to bind a MasterView element to a DetailViewModel property or action, by prepending the detail's property to the target's name. I can't find the specific URL yet, so the example is from memory.
Assuming you have the following classes:
public class MasterViewModel:Screen
{
public property DetailViewModel MyDetails{get;set;}
}
and
public class DetailViewModel:Screen
{
public property string SomeText{get;set;}
public void DoTheBoogie(){}
}
You can add a control in you MasterView named 'MyDetails_SomeText' to bind to the DetailViewModel.SomeText. You can also bind to DoTheBoogie the same way.
I prefer to create a separate View though, named DetailView and add a ContentControl named "MyDetails" in MasterView. This results in a cleaner and more modular design

Magento: Accessing models/blocks from a phtml

Hi I have a situation where I need to look up the number of recently viewed products on catalog/product/view.phtml. In the recently viewed 'product_viewed.phtml' file it calls
$_products = $this->getRecentlyViewedProducts()
to get the recently viewed. How would I access this method from within the catalog/product/view.phtml file?
I don't know where this method is. I've tried searching for it but it doesn't seem to exist. When I write click it in Netbeans and click go to declaration it takes me to
class Mage_Reports_Block_Product_Viewed extends Mage_Reports_Block_Product_Abstract
Actually on the class itself. This class only has _toHtml(), getCount(), and getPageSize() methods.
I just need to know whether there are any recently viewed products.
Any help most appreciated!
Billy
If you look into 'Mage_Reports_Block_Product_Viewed', you will notice:
$this->setRecentlyViewedProducts($this->getItemsCollection());
That 'getItemsCollection' method is defined in the abstract class... And you will notice this abstract class will create a model based on $_indexName defined in the (subclassed) block.
If you just want the collection, you can probably get away with:
$_products = Mage::getModel('reports/product_index_viewed')->getCollection();
And then adding whatever you want to the collection:
$_products
->addAttributeToSelect('*')
->setAddedAtOrder();
// optionally add other methods similar to Mage_Reports_Block_Product_Abstract::getItemsCollection
Another approach that might be more suited would be to create the original block:
$productViewedBlock = $this->getLayout()->createBlock('reports/product_viewed');
On which you can simply call whatever you want:
$_collection = $productViewedBlock->getItemsCollection();
$_count = $productViewedBlock->getCount();
The getRecentlyViewedProducts function is a magical getter that gets the data that was set with setRecentlyViewedProducts in app/code/core/Mage/Reports/Block/Product/Viewed.php (which builds it using app/code/core/Mage/Reports/Block/Product/Abstract.php's function _getRecentProductsCollection).
This is complicated stuff that you don't want to reproduce; its better, IMO to make your own Block that extends Mage_Catalog_Block_Product_Abstract that will give you access to the same functionality, and drop your new block into the page you're working on.

Prism 4.0 : Overriding InitializeShell() Method

I've been going through the documentation for creating Prism applications and setting up the Shell seems to be split into 2 methods, CreateShell() and InitializeShell()
For CreateShell I simply have:
protected override DependencyObject CreateShell()
{
return ServiceLocator.Current.GetInstance<Shell>();
}
The documentation says that code is needed in the IntializeShell() method to ensure it is ready to be displayed. The following is given as an example:
protected override void InitializeShell()
{
Application.Current.MainWindow = (Window)this.Shell;
Application.Current.MainWindow.Show();
}
I have noticed however that if I omit the first line and just call the Show() method it seems to work (MainWindow already appears to have Shell assigned to it). Can you tell me why this is the case, and why we still need to explicity set the MainWindow property here?
Also as I did not specifically register Shell to an interface within the container, how is it able to resolve Shell in CreateShell()?
Question 1: Why does just calling Show() seem to work and why is Application.Current.MainWindow seem to be populated?
There are a few things you should check here. In a typical WPF application, the type for the main window can be specified in the App.xaml. If it is specified, WPF will instantiate one of those for you. This is not desirable because WPF won't use your container to instantiate your shell and any dependencies won't be resolved.
When you run that first line of code in InitializeShell, you'd be replacing the WPF-instantiated Shell object with the one you manually instantiated.
I looked at the code for the MEF and Unity bootstrappers and I don't see anywhere that MainWindow is being set, but I don't know if you might have customized the base bootstrappers, so that's something else to look for.
Show() works because you are simply showing the window you instantiated and the WPF-instantiated one isn't shown. This is my theory, but without seeing your code, it'd be tough to say for sure.
Question 2: How can Unity resolve something that hasn't been registered?
Unity can always resolve a concrete type, regardless of registration. It cannot resolve non-concrete classes that haven't been mapped to a concrete type. This is why Resolve<Shell> works, but Resolve<IMyInterface> doesn't unless you register a type.

zend_form access parent form element

I couldn't find any reference on how to use a parent form element in a subclassed form. May be because it's obvious to everyone but me. It's got me stumped. This is what I tried.
At first, within my form constructor I called
parent::__construct($options = null);
then accessed the parent elements like this
$type = parent::setName($this->type);
The problem was that ALL the parent form elements would display whether explicitly called or not. Someone said, "don't use __construct(), use the init() function instead. So I changed the constructor to init(), commented out the parent constructor, then ran the form. It bombed saying it couldn't pass an empty value for setName(). I commented out all the seName() calls and the form ran, but only displayed the elements instantiated in the subclassed form.
My question is this: If I don't use the parent constructor, how do i get and use the parent's form elements?
Solved: Since the constructor was switched to init, the call to the parent also needed to be switched. Easy for someone with php background. Not so much for one who doesn't.
Use
parent::init();
Solved: Since the constructor was switched to init, the call to the parent also needed to be switched. Easy for someone with php background. Not so much for one who doesn't.
Use
parent::init();
You should learn OOP principles first. Obviously you have no understanding of it whatsoever. You need to call parent::init() in you Form_Class::init() method as you wrote, but why? Because otherwise the parent method is not called and is overriden by the From_Class method.
Other thing is that when you have a parent class "SuperForm" with input and submit, then your "SuperForm_Subclass" would have the same elements assigned. There is no need to use "parent::*" to access element (only exception would be if you used static SuperForm variable to store them - which makes no sense).
You can easily use $this->inputElement and $this->submitElement inside your SuperForm_Subclass like you would in the SuperForm class.
In your example you could used the __contruct() as good, but with the same condition of calling the parent constructor. You would be able to access elements generated there too...