How to organize JS files in a Appcelerator Titanium project

26,874

Solution 1

Titanium itself is essentially MVC given that your app.js file is the main controller and each View you create is the view and you pass (or set) model data against the view.

In Titanium, you can decompose your application using a couple of nice built-in mechanisms:

  1. Titanium.include - Titanium.include allows you to include one or more JS files in place much like the C #include compiler directive. You can put common functions and JS classes in this file and then include them where ever you want them imported and available.

  2. Titanium.UI.createWindow - you can create a new View as as a property of the new Window pass in a URL to another JS context which will create a new JS sub-context and allow you to maintain its own variable space (but still give you access back to your parent).

Also, in Titanium, you can create folders that allow you to logically organize your application in a way that is suitable to you and your application.

Edit: Today, the Titanium.Include method is deprecated. As mentionned in the documentation, we should create a CommonJS module and use the require() statement.

More information about this statement : Require

More information about modules : Modules

Solution 2

As I was not finding an appropriate MVC solution for a Titanium mobile project, I came up with the following approach. For small apps this might be over-engineered but could help for maintaining growing applications.

Folder structure:

/Resources
  /model
  /view
  /controller
  /ui
  /iphone
  /android
  app.js
  app.jss

For separating views, models and controllers a namespace is needed, so we define it in the app.js, which is our main controller:

var app = {
  view: {},
  controller: {},
  model: {},
  ui: {}
}

Within the folders we place single JavaScript files for each component. For this we could either use a lightweight JavaScript OOP library, such as MooTools or Prototype or define simple JS functions as our objects. If you also want to inherit from parent classes, a library definitely makes sense.

Examples:

# Resources/controller/MyController.js
app.controller.MyController = function() {
   return {
      getView: function() {
         return new app.view.MyView().getView();
      }
   }
}

# Resources/view/MyView.js
app.view.MyView = function() {
   return {
      getView: function() {
         return Ti.UI.createWindow({...});
      }
   }
}

# Resources/view/MyModel.js
app.model.MyModel = function() {
   return {
      some: "data",
      foo: "bar"
   }
}

After that we can include all needed model/view/controller classes with Ti.include() in the app.js file and reference the components with our namespace:

Ti.include("controller/MyController.js");
Ti.include("view/MyView.js");
var myController = new app.controller.MyController();
var myView = myController.getView();
myView.open();

The MVC approach would now presume that the controller "controls" the state of the view and passes data from the model into the view. The view consists only of UI elements and properties for styling. Any action which is made in the UI fires an event, which tells the controller to perform the desired action.

But of course, the exact definition of MVC might be different according to your personal taste ;)

Solution 3

This also may help: A basic struct of how to organize a Titanium mobile project: https://github.com/krawaller/Struct

Solution 4

Allow me to update this question since most of the responses are superseded. In Q4 2012, Appcelerator released the Alloy MVC (beta) Framework along with the latest IDE and SDK release, Titanium Studio 3.0 and SDK 3.0. Alloy is completely integrated with Studio, so it's quite easy to get a basic app running in less than 15 mins. Alloy introduces a significant folder restructure: The /app folder is now where all the development code resides.

The /Resources folder, where code used to reside, is now the updated equivalent of the /build folder. Compiled code in /Resources is overwritten at each build.

I created a short introductory primer (screencast) on creating an Alloy project. You can view it via my dropbox folder.

Create Alloy Project

Share:
26,874

Related videos on Youtube

Tilo Mitra
Author by

Tilo Mitra

I'm a Software Engineer that enjoys writing about JavaScript.

Updated on June 19, 2020

Comments

  • Tilo Mitra
    Tilo Mitra almost 4 years

    I have recently started creating an iPhone application using Appcelerator's Titanium. Since the application is essentially all JS, I needed some advice on how I should organize this project.

    It's becoming very easy to just create long procedural files for each view in the application. Is there a way I can incorporate MVC, or some structure to the project?

    Thanks, I appreciate it. -Tilo

    • conny
      conny over 11 years
      While the question remains relevant, note that some of the answers are growing outdated: by now there some patterns which are mentioned in the tutorials and official docs - even the good old sample app KitchenSink (aka king of rats' nests) has been refactored to better reflect current good practice.
  • philoye
    philoye about 13 years
    Here's a helpful blog post that explains what is happening in that GitHub repo.
  • mkind
    mkind almost 13 years
    like your solution. did it the same way and have made good experiences.
  • Jonathan Clark
    Jonathan Clark over 12 years
    Like it a lot and would really like to use it. How can I use it in my app?
  • Ellery Familia
    Ellery Familia about 10 years
    I like this. Would the 2014 non-alloy version differ only by the usage of require() instead of Ti.include()?
  • piotr.d
    piotr.d almost 10 years
    I would argue with the statement that
  • piotr.d
    piotr.d almost 10 years
    (please disregard my comment above, I cannot delete it anymore :/) @jhaynie, I would argue with the statement that Titanium itself is essentially MVC. When dealing with so-called classic Titanium project, there is almost no structure enforced. Specifically, there are no controllers or models. You can come up with your own structure and make it MVC-like, but classic approach is not MVC per se. Titanium Alloy (although not released at the time you posted your answer) is an MVC framework, on the other hand. It enforces specific project structure and offers real separation of concerns.
  • Justin Vincent
    Justin Vincent over 9 years
    Thank you! You saved me pulling out my hair with this information.
  • Justin Vincent
    Justin Vincent over 9 years
    Is there a way I can split up controller javascript into multiple files so It doesn't have to be one long .js file?
  • Mike S.
    Mike S. over 9 years
    @JustinVincent you can split your controller files however you like. Just be sure to "require" them in the original container. Also, keep them organized in a way that makes sense to you. If you split code from foo.js into bar.js and foo needs to know about it, simply add to foo var bar = require('bar.js')
  • Mike S.
    Mike S. over 9 years
    @JustinVincent correction: for the require, it should be var bar = require('bar');. Don't add the file extension. Then, in foo.js, you can reference bar's code with bar.doStuff();
  • Dragon
    Dragon over 9 years
    For those who are checking it late, Ti.include() is Depreciated.