Notes on Nativescript: my first steps into mobile development
Nick W Apr 19 '17
What follows is simply a few reflections on my experience, and what I would recommend for anyone looking to get started.
NOTE: I am in no way an expert; I simply want to share my experience working with Nativescript as a non-expert, JS-novice, mobile-ignorant layman.
Lesson #1: Avoid the paradox of choice
Nativescript has some of the best documentation of any framework I have used. It has clearly worked minimal examples, and walks you through a increasingly complex grocery list app to get the hang of things. All was going well, so to jump in, I cloned a demo app that used the drawer navigation system I had in mind.
Lesson #2: Multiple ways to skin a cat
Similar to the last lesson, Nativescript itself is very flexible. When I first got started, it seemed straightforward enough: js for the logic, xml for the structure, and css for the style. How hard can it be?
What I learned after a while working on my app was that that understanding is a simplified version of reality. If you want (and you probably will, once you see how it can help), you can set the style in the xml sheet, and set the structure of the page in js. Why would you want to do that? Simply, it allows you to bind application logic to the layout of pages, so that you can dynamically change the UI based on certain things. This is an incredible useful feature, but (I felt) poorly explained in the literature.
This led to lots of "huh?" moments looking at examples. The Nativescript docs do have examples of the different ways of doing things, but the way the tutorials go, it is not immediately apparent. Look at the example below for making a grid-layout from the docs, for instance.
<GridLayout columns="80, *, auto" rows="auto, *" > <Button col="0" /> <Button col="1" /> <Button col="2" /> // by default column and row are set to 0 <Button row="1" colSpan="3" /> </GridLayout>
or, the js:
//var layout = require("ui/layouts/grid-layout"); var gridLayout = new GridLayout(); var btn1 = new Button(); var btn2 = new Button(); var btn3 = new Button(); var btn4 = new Button(); gridLayout.addChild(btn1); gridLayout.addChild(btn2); gridLayout.addChild(btn3); gridLayout.addChild(btn4); GridLayout.setColumn(btn1, 0); GridLayout.setColumn(btn2, 1); GridLayout.setColumn(btn3, 2); GridLayout.setColumnSpan(btn4, 3); // ItemSpec modes of the column refers to its width. // Absolute size of the column var firstColumn = new ItemSpec(80, GridUnitType.pixel); // Star width means that this column will expand to fill the gap left from other columns var secondColumn = new ItemSpec(1, GridUnitType.star); // Auto size means that column will expand or shrink in order to give enough place for all child UI elements. var thirdColumn = new ItemSpec(1, GridUnitType.auto); // Star and Auto modes for rows behave like corresponding setting for columns but refer to row height. var firstRow = new ItemSpec(1, GridUnitType.auto); var secondRow = new ItemSpec(1, GridUnitType.star); gridLayout.addColumn(firstColumn); gridLayout.addColumn(secondColumn); gridLayout.addColumn(thirdColumn); gridLayout.addRow(firstRow); gridLayout.addRow(secondRow);
Its a bit hard to see whats going in in the js example. The xml is pretty clear: define a grid with some rows and columns, and place 4 buttons there.
The js does the exact same thing, but from the js file instead of the xml.
That is cool, but it is hard to see immediately what is going on. I found that when I was trying to reuse code examples, a lot of time ended up being spent figuring out whats going on.
Lesson #3: Choose a binding scheme and stick with it.
I didn't come from a web background, so I wasn't familiar with DOM issues that Nativescript attempts to get around. I found the binding schemes available in Nativescript very confusing. Again, the docs are good, but it took some serious tinkering to understand what was going on with static, one-way, two-way, parents, children, inheritance, etc. What further complicated things is the way different people handle it.
I followed the scheme set up by the groceries app for version 0.1 of my app. But as things got more complex, I came across this guide that re-defined how I looked at the binding model. The one laid out in that guide made more sense to me (I needed events to update in real time without waiting for a "submit" event), so I ended up re-writing a lot of the previous logic to reflect the new model for the next version.
All this to say, read lots and look around at different ways of using Nativescript before getting started. I started off with very little idea of what I was doing, and ended up spending a lot of time reworking things as my understanding of the framework was updated. That being said, it is a great framework, and I look forward to using it more in the future for other projects!