Virtual Insanity with NativeScript Views and Angular 2 -

June 20, 2016 0 Comments nativescript, angular 2

Virtual Insanity with NativeScript Views and Angular 2 -

Futures made of virtual insanity now
Always seem to, be governed by this love we have
For useless, twisting, our new technology
Oh, now there is no sound for we all live underground

- Jamiroquai

We all love to twist our technology, sometimes motivated by useful objectives and other times for useless fun. But what if that useless fun led to something useful?

Unless you truly have been living underground where there may be no sound, you have probably heard of NativeScript, the open source cross-platform framework for building native apps using JavaScript, CSS, and XML. But I'm not really here to teach you NativeScript today, but to discuss an interesting twist.

Jeff Whelpley suggested this twist a couple months back to me in a chat, which prompted this post, which started:

I am interested in expanding the idea of NativeScript modules from iOS and Android to the web. I am just starting to get into NativeScript, so there may be some things I am missing here, it seems like there is no reason why you can't translate something like this:


<span>hello, world</span>

I must admit that my first reaction was mixed. Creating NativeScript view templates from existing HTML made more sense to me, but I slept on it and found a new awakening. Additionally, I knew that working one direction (i.e. NativeScript Views -> DOM Views) could pave a path to go the inverse direction, which is what I ultimately wanted.

Let's entertain this for a moment. What if we could use NativeScript views to build web apps? Now, we really wouldn't want to build an entire web app with NativeScript views - that would be rather silly - but there's some real use cases here.

For example, what if you had invested resources and time into building that beautiful native mobile app your client loves with NativeScript and now they are asking if you can build a web app to engage a different market segment? You might find yourself wondering "How could we get this awesome app on the web?" It may help to generate a quick web prototype to get your web effort rolling.

Welcome to "futures made of virtual insanity"

That right there is one view file using NativeScript XML which can be rendered in a NativeScript app AS WELL AS on the web. This is how that NativeScript view looks rendered in the DOM:

This creates a few opportunities to name a few:
* The ability to statically render web templates from a NativeScript (only) app;
* In the future, you could run your views through a compiler which would spit out HTML equivalents to begin developing your complimentary web app quickly;
* Interop/Reusability between NativeScript and web templates;
* The ability to invert the rendering: statically generate NativeScript view templates from HTML web templates to quickly bring a web app into the NativeScript world.

There's no magic here. With the help of the amazing Angular 2 development platform, a new world of possibilities has opened up.

Some Examples

Let's take a look at the composition of a couple components starting with the ActionBar:

@Component({ selector: 'ActionBar', templateUrl: 'action-bar.component.html' }) export class ActionBarComponent { @Input() title: string; }

And here is the contents of the action-bar.component.html template:

This may appear surprisingly simple and it is. The DSL of NativeScript views are incredibly concise and well constructed, which lends itself to simple parallels in the DOM.

Let's take a look at another, StackLayout:

@Component({ selector: 'StackLayout', templateUrl: 'stack-layout.component.html' }) export class StackLayoutComponent {}

And the stack-layout.component.html template:

Again simple. However to fully support NativeScript's DSL, we still need to implement the horizontal layout here. Flushing out the rest of the details is still in the works, but let's look at a slightly more interesting example, ActionItem:

@Component({ selector: 'ActionItem', templateUrl: 'action-item.component.html' }) export class ActionItemComponent implements OnInit { @Input('ios.position') iosPosition: string; @Input('android.position') androidPosition: string; constructor(private el: ElementRef) {} ngOnInit() { if (this.iosPosition === 'right' || this.androidPosition === 'popup') { let cls = 'btn-right'; let currentClassName = this.el.nativeElement.className; this.el.nativeElement.className = currentClassName ? [currentClassName, cls].join(' ') : cls; } } }

And the action-item.component.html template:

We can see more of NativeScript's DSL implemented.

Now what happens when some of the DSL matches actual DOM elements? Button happens to be one of those and in those cases, we want our component to act a bit like a pass-through (i.e. it should not get in the way):

@Component({ selector: 'Button', templateUrl: 'button.component.html' }) export class ButtonComponent { @Input() text: string; constructor(private el: ElementRef) { this.el.nativeElement.setAttribute('type', 'submit'); } }

And the template button.component.html:

Here we adapt the NativeScript DSL to be more like its DOM counterpart and otherwise get the heck out of the way.

Let's look at one more interesting example where the DSL is different enough to require some special handling as is the case with Image:

@Component({ selector: 'Image', templateUrl: 'image.component.html' }) export class ImageComponent implements OnChanges { @Input() src: string; public imgSrc: string; ngOnChanges() { if (this.src) { if (this.src.indexOf('~') === 0) { // local file this.imgSrc = this.src.replace('~/', ''); } else { this.imgSrc = this.src; } } } }

Ad the image.component.html template:

The consideration here is that with a NativeScript Image, users can use ~/ to indicate a local resource in their app folder. Of course, in the browser there is no equivalent to this, so we must consider that here as a relative resource to a web server root.


Working through this exercise was incredibly eye-opening to me not only to the exciting future for NativeScript, but the awe-inspiring greatness that is Angular 2. I see the possibility for any DSL view template to be rendered on the web using this approach. Got a large old ActionScript/MXML application laying around that needs to be webified? Yep, sure, it could be done.

Again, a lot of the motivations behind this effort are explained here.

You can get involved with this effort and help shape its direction by contributing here.

The jury is still out on the insanity of it all.

Header image courtesy of japrea

Nathan Walker
Nathan is a Senior Software Engineer at Infowrap with over 15 years experience in web/mobile application development. His varied background rooted in the world of design and the arts (from magazine layouts to video production/documentaries as well as former Nashville musician) helps provide a unique foundation to problem solving. From Javascript, Objective C, Swift, Java, Ruby, Angular to NativeScript, Nathan crafts his code like he would design an ad, craft a cinematic story, or write a billboard hit. Always striving to balance his right brain approaches with his left brain sensibilities, he focuses on bringing solid results to a diversity of business environments.

Virtual Insanity with NativeScript Views and Angular 2 -

Tag cloud