Learning Appcelerator Part 2 (ListViews and Models)

In the first tutorial we learned how to create a simple bio metric login screen. Building on that example we can now do a follow up screen that will transition to a list of Users.

Get the code for this Demo

Building on the previous tutorial we will be adding a new View called userList.xml This is pretty boiler plate code that contains a ListView. The important thing to note in this file is the Collection tag. This is what will instantiate the model and get it ready to pull data out of it. When we do it like this our controller can then call fetch and retrieve the list of users. We also are using a templating syntax in for {Status} and {Name}. Lastly to tell the list to use our model we will add dataCollection to our ListSection.

VIEW

userList.xml
<Alloy>
	<Collection src="userModel"/>
	<Window class="container" id="userList">
		<ListView width="100%" onItemclick="userDetail" defaultItemTemplate="listTemplate">
			 <Templates>
                <ItemTemplate id="detailTemplate" name="listTemplate">
                    <ImageView bindId="status" class="rowStatus" text=""/>
                    <Label bindId="name" class="rowUserName" text=""/>
                </ItemTemplate>
            </Templates>
			<HeaderView>
				<View backgroundColor="#ddd" height="30">
					<Label class="status">Online</Label>
					<Label class="userName">User Name</Label>
				</View>
			</HeaderView>
			<ListSection dataCollection="userModel">
				<ListItem  status:image="/images/{status}.png" name:text="{name}" height="40" />
			</ListSection>
		</ListView>
	</Window>
</Alloy>

Like in our previous example we will do some styling for our list.

userList.tss
".container" : {
  top:75
},
".status" : {
 left : 5
},
".userName" : {
 left : 75
},
".rowStatus" : {
 left : 10,
 width : 25,
 height: 25
},
".rowUserName" : {
 left : 75
}

CONTROLLER

For our userList controller we are going to call fetch() Fetch is a built in backbone.js function that will pull data from our model using the built in Sync functionality of backbone.

userList.js
Alloy.Collections.userModel.fetch(); 

Of course in order to get to our list well need to change the login file index.js from an alert to a way to transition to our new screen. Here we grab our userList controller view and we want to call open() to transition to it. We are going to make the screen do a flip transition from Left to right at 1/2 second. Now you will see an condition here because the built in transition on Android won’t flip so in this case we just want to slide it in for Android.

index.js
TiAuth.doAuth = function(didPassBio) {
    if (password == $.passWrdTxt.value && userName == $.userNmTxt.value || didPassBio) {

        var win1 = Alloy.createController("userList").getView();
        if (OS_IOS) {
            win1.open({
                transition: Ti.UI.iOS.AnimationStyle.FLIP_FROM_LEFT,
                duration: 500
            });
        } else {
            win1.open();
        }

    } else {
        alert("You have failed to login!" + Alloy.Globals.isIphoneX);
    }

};

In our Alloy.js file we need to set up our data so we can display it. Since Alloy.js gets called first before all our controllers this is the perfect place to add our mock up data. In this case we have a static file with some json data in it. So we can grab this data by looking through the file system and grabbing it. Then we will parse it and add it to our mocx collection. For more on how this file works. It basically overrides the backbone.js Sync function to add data to its collection.

assets/mockData/alloy.js
var mocx = require("mocx");

Alloy.Globals.isIphoneX = (Ti.Platform.displayCaps.platformHeight == 812);

(function constructor(){

// Create Mock Users from fake data
var file = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory,'mockData/users.json');
	preparse = file.read().text,
	response = JSON.parse(preparse);
    
	mocx.createCollection("userModel", response.UserStats);
})();

MODEL

The model code is pretty boiler plate too. When you create a new model using Appc Studio it will build this file for you. The only things you will need to make sure are correct are the collection_name and depending on your json structure you might need to add a parentNode function. In our case we have a parent node of UserStats. If we didn’t have that we wouldn’t need to add that parentNode.

userModel.js
exports.definition = {
	config: {
		adapter: {
			type: "sql", // <-- name of custom adapter
			collection_name: "userModel"
		},
		// Gets the parent node of our Array
        parentNode: function(data) {
            data = data || [];
            return data.UserStats || data;
        }
	},
	extendModel: function(Model) {
		_.extend(Model.prototype, {			
		});
		return Model;
	},
	extendCollection: function(Collection) {
		_.extend(Collection.prototype, {
		});
		return Collection;
	}
};

Our fake data.

user.json

{
	"UserStats": [
		{
			"name": "Darren",
			"status": "online"
		},{
			"name": "Aaron",
			"status": "online"
		},{
			"name": "Bill",
			"status": "offline"
		},{
			"name": "Steve",
			"status": "online"
		}
	]
}
Loading Facebook Comments ...