I need to perform an action after switching to a view.
The first time you switch to a view 'activate' and then 'compositionComplete' is called.
After that only 'activate' is called.
It would appear that 'activate' is called before the view has finished being displayed and this is causing issues with a JavaScript control I'm using (Bing Maps V7).
I've been using Hooking Lifecycle Callbacks as a reference but there doesn't appear to be a suitable callback to hook in to.
Is there another event or approach I can use to tell when the DOM has finished changing to the view?
It sounds as though your module is a singleton instead of an instance. Is that true? If you create an instance-based module, the module will be created anew each time it's activated. That will cause the compositionComplete to re-execute.
The activate handler is good for preparing data that will ultimately be displayed in the view. compositionComplete is best for handling matters that depend on a fully-constructed DOM.
We use Bing Maps AJAX v7 as well, and I've always placed it in an instance-based module.
To create an instance-based module, if you're not familiar, make sure your viewmodel returns a constructor function instead of an object literal.
Have you tried placing the Bing initialization in attached? Or creating a custom binding for it? Any third party libraries i use will always be initialized in attached, and if its something i want to use more than once, ill either create a custom binding for it or create a widget.
Related
Let's use an example of a blog built by Marionett. The blog post is a sub app and hook the route post/:id. It also has a controller, inherited from Marionette.Controller. Quite normal.
Each hit to post/:id will create a new controller instance, managing the related model and views. The controller instance will trigger App.vents but won't listen on App.vents.
My question is, since there will be so many instances of the controller created when an user navigates around, should I concern the close of the instances when there are a close() method available in controller? Will there be memory leak if not closing them?
Thanks.
There could be a memory leak depending on what's inside your controllers. Also if you're controller is using listenTo to watch events on other models/objects you could get a build up of zombie events. Without seeing your code it would be hard to say for sure.
In general, I think why not just close the controllers? The way I do this (from BackboneRails tutorials) is to have the first view controller the renders (typically a layout) as the main view and then bind to the view's close event--when the view closes the controller will call close on itself. You can build this into your base controller so it happens automatically. This has worked pretty well for me...
I've created an admin component and now need to insert text on each page of the installing client. So I thought of using the function onContentPrepare but it's a method of a JPlugin class (a content plugin class to be exact).
Is there a way to invoke the component from the view in the same way like a plugin?
Short answer: No, you have to write a plugin. But that's not a big thing.
Long answer: On each request, exactly one component is called. Plugins are triggered at certain events within the control flow. The onContentPrepare event is triggered by the components (not from the Joomla! framework), so some components might not support it. Nevertheless, you can get access to the content of any component through plugins anyway - just use the onAfterRender event of the system plugins.
I'm asking this because I really don't know where I should handle events of my dynamically created window.
When someone clicks on a desktop icon, the window (if it doesn't exist) will be dynamically created. Should I create a controller when creating the window and hook to it? If yes, how?
Here you can read different approaches I've thought about:
Create a controller that will instanciate the Window (as its view), I will handle everything there
Create the window only and hook everything in my taskbar controller (which is where the window is created). In this case, the Taskbar controller will become very big.
Pre-create all window controllers and eventually windows too and hide them (when page is ready). Then just show/hide them, so I will have "static" references to all controllers with getController in Application
Which approach should I use?
Edit 1:
I'm trying to dynamically instanciate (and reference it through another controller) a controller. I'm having hard time expecially in referencing it. Any suggestion on how it should be done?
I found Ext's MVC unusable with desktop demo as it's possible to have multiple windows (views) of the same type tied to a single controller. Each window has it's own state and it's hard to differentiate between the views in the controller.
I solved the problem by myself: I preinstanciate the controller as I do with all controllers, by inserting them in Application controllers array. After this, I instanciate the view on that controller when a method is called, then I simply use refs to access this view.
The method is quite clean and using refs feel so good. Obviusly the controller has a method hasWindow which checks if the controller view has been created already.
I have a Conductor<MyItem>.Collection.OneActive ViewModel and try to attach the application bar buttons to methods of MyItem with cal:Action.TargetWithoutContext="{ Binding ActiveItem }". My view is a Pivot, if someone wonders why am I trying to attach the application bar to a child ViewModel. The compiler says "Property 'TargetWithoutContext' is not attachable to elements of type 'AppBarButton'." Though it works with normal buttons elsewhere in the view.
How can I get it work? Or maybe any workaround?
The AppBar functionality that Caliburn.Micro provides is a hack due to the flaws in the underlying framework, which doesn't allow arbitrary binding. Unfortunately, we can't support TargetWithoutContext. For AppBars the target will always be the page's view model and messages can only be directed to it. If the page's view model is a conductor, and you want a child to receive the message, you could have the conductor receive it and then forward it on to its ActiveItem.
Unfortunatly the ApplicationBar is not bindalbe as it is not Part of the Silverlight Framework.
You can only interact with the Application via the Code Behind File of the Page which uses the ApplicationBar.
You have to register the Click Event and invoke the Action form the code Behind.
The WP7 ApplicationBar is just a simple wrapper around the native shell and doesn't support data binding at all. However, there are a couple of workarounds available.
http://caliburnmicro.codeplex.com/discussions/232742
I am working with someone else's code. The code was originally designed so that data would dynamically create controls (and sub-controls of those controls...) on the OnInit event on numerous web control panels. And then later validation methods would check those dynamically created controls for valid data. This continues to work just fine for my web site. However, I need to be able to validate that data without my website (as in this will just be server side). The simpilist solution appeared to be to just have the panels initialize and then run the validation methods. That'd be great...if I could figure out how to initialize those panels server side without a web page.
Can this be done? Is there any way to get a panel to initialize without having a page to display that panel?
That way lies madness - you could use reflection to call the control's InitRecursive method, but it needs a Page (among other things) to run correctly.
You should extract the validation code into a new class that you can call from your server code an change your WebControl to use that class as well.
Try RenderControl.