How can I replace RegionManager instances on Marionette 3 - backbone.js

I am currently upgrading a project from Marionette v2 to v3 but it seems all of the functionality of the region manager was added into the View class.
My project has several instances of
Marionette.RegionManager.extend({
regions: {
...
}
})
I was wondering if there is a way of directly converting v2 code like this into v3 code.

I found that the region manager can be replaced by a view, acting as the root for all other views. It is sufficient to add it to the application as stated in the Application documentation
var Mn = require('backbone.marionette');
var RootView = require('./views/root');
var App = Mn.Application.extend({
region: '#root-element',
onStart: function() {
this.showView(new RootView()); // Which is your old region manager
}
});
var myApp = new App();
myApp.start();

From the 3.0 release blog:
RegionManager
Marionette.RegionManager was removed. This publicly exposed class was mostly used as a common
class used between LayoutView and Application.
The upgrade guide doesn't seem to mention RegionManager at all.
If you are looking for a codemod or something I'm not aware of any. But there is this marionette-3-patch for backwards compatibility with marionette 2, which you can use for upgrade and gradually re-write the 2.x syntax manually or create tooling.

Related

Future proofing Angular apps with ES6 features

What is the recommended (if there is one) future-proof way to write controllers, services and directives in ES6 (using Traceur) so that the most of same code can be used with AngularJS 2.0. I realize that AngularJS 2.0 is still on the drawing board but if I were to start a new app today what style or conventions do I follow so migrating to 2.0 will hopefully be less painful.
Declaring a class and then passing a reference to that class into the controller or service is one point i see:
var app = angular.module('myApp', []);
class MainCtrl {
....
}
class MyService {
....
}
app.controller('MainCtrl', MainCtrl);
app.service('MyService', MyService);
Should the MyService class be moved to a separate file so that potentially in the future I could just export it and have it available to be injected?
What are some other things to keep in mind as I work on a new project using AngularJS (<= 1.3.x) and ES6?
Update
After some digging around I wrote a series of blog posts talking about my findings on my blog
The angular team at ngEurope confirmed today that the $controllers, $scopes, $services and jqLite of 1.x will cease to exist in Angular 2.0. There will also be a brand new router, which they intend to backport to 1.3 in the coming months.
To prepare for migration they suggested just following the best practices/styles/conventions that have evolved in the community so far, and when 2.0 is ready (sometime next year), they'll work out the best way to migrate from there.
Also, they said that 1.3 will be fully supported for at least a year and a half after the release of 2.0.
You can define ES6 classes and add them in existing Angular 1.x applications. You will need to set up transpiling etc, but here is a general example:
class PersonService{
constructor(){
}
getPerson(){
return 'Jim Smith';
}
}
angular.module('app').value('PersonService', PersonService);
class GreetingService{
constructor(){
}
sayHello(){
return 'Hello from ES6!';
}
}
angular.module('app').service('GreetingService', GreetingService);
More details here: http://www.syntaxsuccess.com/viewarticle/552dc66f955de264e1fbbaee

Sharing views and content across Nancy projects

Is there a super duper happy path for sharing views and site content across Nancy projects?
For example, I'd like to run the same site via self hosted / IIS.
The easiest way to do that is to put all of the actual application code into a class library - that is your modules, views, js, css, bootstrapper and whatever supporting code you have. You then setup a view location convention in your Bootstrapper such the view can be found in both a web server and self hosted context. This could be the ResourceViewLocationProvider:
public class Bootstrapper : DefaultNancyBootstrapper
{
protected override NancyInternalConfiguration InternalConfiguration
{
get
{
return NancyInternalConfiguration.WithOverrides(
x => x.ViewLocationProvider = typeof (ResourceViewLocationProvider));
}
}
}
Alongside that you can have a web projects, with e.g. nancy.hosting.owin setup up and a project reference to the class library with the application code. Similarly you can have a console application with just nancy.hosting.self setup and a reference to the class library.
I describe this setup in more detail on my blog and in my Nancy book.

Is an Application object more than just a container / module?

I've been rewriting an application of mine using Marionette, but I'm a bit confused.
In every usage I've seen, the Marionette.Application object appears to just be used as a container / top-level module (which it is) and nothing more:
App = new Marionette.Application();
App.module('myModule', function(args) { /* ... */ });
App.on('event', function() {});
While I have been testing, it has become necessary to occasionally create a new Application instance and pass in different options. Because of this setup, it means I will need to also call the necessary functions (e.g. addInitializer, addRegions, .module) on my new instance.
This is in contrast to other objects (like Models or Views) where most (if not all) of the configuration takes place within the configuration options, before an object has even been instantiated:
MyModel = Backbone.Model.extend({
idAttribute: 'different-id',
defaults: {
'content-type': 'product'
},
sync: function() {
// override a function
return false;
}
});
Unlike these objects, we must instantiate the Application before doing any configuration.
Am I misunderstanding the purpose of the Application object? Is it just supposed to be a generic top-level container?
The Application is the centerpiece of your SPA, and you should have exactly one instance running on any given page. Each of your site's major capabilities will branch from the App in the form of Modules; any coordination that happens between modules should be set up at the Application level. Generally speaking, you'll define your app, define a bunch of modules, add initializers to setup comms between the modules, and then start the application, which will automatically trigger the startup of all modules (unless configured otherwise).
If you find yourself using more than one application on a single page, you probably haven't abstracted enough; the App really should only contain logic that will be shared across modules; if each module is completely self-contained, then you're right - your App is likely to look like a very generic container.
HTH...
Straight from the doc
The Application is meant to be instantiated directly, although you can extend it to add your own functionality.
It is used as the top-most level container and help to provide facilities to 'tie' all sub-components together.

Ninject Registration with Silverlight and Prism

I am using Ninject as my bootstrapper (mainly because of convention based registration and its fluent API).
We are using Prism 4 Navigation Framework RequestNavigateAsync call to navigate from one page to the other. The API looks into the container for named instance of the object and resolve the view / viewmodel that it needs to navigate to. Here's Unity syntax for this.
Its recommened to use
container.RegisterType("InboxView"
instead of container.RegisterType("InboxView")
In Ninject, how can I get similar effect so that it gels with Navigation framework easily?
Can you help provide some code / documentation which shows how to register named instances in Ninject (that might help).
Assuming this is your syntax in Unity
var container = new UnityContainer();
container.RegisterType<object, InboxView>("InboxView");
The equivalent syntax in Ninject is
var kernel = new StandardKernel();
kernel.Bind<object>().To<InboxView>().Named("InboxView");

Does Caliburn provide a way to get a reference to the container from anywhere?

I'm currently messing around with Rob Eisenberg's Caliburn framework. When looking at the documentation that is provided on http://caliburn.codeplex.com there is an example of how to resolve a Caliburn service from the container.
It's something along the lines of this:
SimpleContainer container = new SimpleContainer();
CaliburnFramework
.ConfigureCore(container)
.WithCommonDialogs()
.WithPresentationFramework()
.Start();
var service = container.GetInstance(typeof (IService)) as Service;
However what I am missing is a way to get a reference to the container anywhere in the app. Like this:
var service = Caliburn.Container.GetInstance(typeof(IService))as Service;
Do I have to build a custom static class that holds a reference to the container or is there something already built into Caliburn?
Thanks in advance and best regards!
The latest trunk version of Caliburn automatically registers the container on framework startup as an service locator. You just have to reference Microsoft.Practices.ServiceLocation on your code and then ask the ServiceLocator for a instance of your service.
var service = ServiceLocator.Current.GetInstance<IService>();
Hope that helps.

Resources