SC.SourceListView controlee par un SC.TreeController avec SproutCore

Voici un rapide tutorial qui vous permettra d’afficher une SC.SourceListView contrôlée par un SC.TreeController.

Prérequis :

  • Quelques connaissances sur SproutCore
  • Sproutcore 1.6 installé
  • Ruby 1.8 installé (Normalement installé sur tous les mac)

Pour commencer je vous propose de générer un projet de test. Ouvrez le Terminal et tapez la commande suivante :

$ sc-gen project SourceListExample

Cette commande génère donc un dossier avec votre nouveau projet. Rendez-vous dans le dossier généré :

$ cd source_list_example

et générez l’application :

$ sc-gen app SourceListExample

Il nous faut créer un contrôler pour gérer les comportements de notre liste. Toujours dans le Terminal :

$ sc-gen controller SourceListExample.TreeController

Enfin, dernière chose à générer, le modèle. Nous utiliserons 2 entités, les groupes et les utilisateurs.

$ sc-gen model SourceListExample.User
$ sc-gen model SourceListExample.Group

Tous nos fichiers sont en place. Nous pouvons passer à l’édition.

Ouvrez le fichier Buildfile se trouvant à la racine de votre projet et éditez le contenu afin d’ajouter les frameworks qui nous seront utiles. Remplacez :

config :all, :required => :sproutcore

par :

config :all, :required => [:sproutcore, 
  "sproutcore/datastore", // Base de données
  "sproutcore/desktop", // SplitView et SourceListView 
  "sproutcore/ace" // Theme
]

Ouvrez maintenant le fichier apps/source_list_example/resources/main_page.js, nous allons configurer notre vue.  Remplacez la déclaration de mainPane pour obtenir ce code :

mainPane: SC.MainPane.design({
	childViews: 'mainView'.w(),
	// Notre vue principale sera une SplitView pour illustrer notre exemple
	mainView: SC.SplitView.design(
	{
		defaultThickness: 200,
		topLeftMinThickness: 150,
		topLeftMaxThickness: 250,
		layout: { top: 0, bottom: 0, left: 0, right: 0 },
		// Vue de gauche
		topLeftView: SC.ScrollView.design(
		{
			contentView: SC.SourceListView.design(
			{
				// Liaison du contenu de la vue avec le controlleur 
				contentBinding:	'SourceListExample.treeController.arrangedObjects',
				// Propriété de l'objet Record qui positionnera la valeur des labels des items de la vue
				contentValueKey: "name"
			}),
		}),

		// Vue de droite
		bottomRightView: SC.LabelView.design(
		{
			textAlign: SC.ALIGN_CENTER,
			value: ""
		}),

	})
})

Ensuite, ouvrez le fichier contrôleur apps/source_list_example/controllers/tree_controller.js. Dans cette classe il s’agit juste de changer la classe parent afin d’utiliser un SC.TreeController et non un SC.ObjectController.

SourceListExample.treeController = SC.TreeController.create({})

Occupons-nous maintenant du contenu de notre liste, en passant par les modèles. Complétez les 2 classes modèles générées précédemment, respectivement apps/source_list_example/models/group_model.js et apps/source_list_example/models/user_model.js comme suit :

SourceListExample.Group = SC.Record.extend({

    name: SC.Record.attr(String),
    // Définit si le noeud dans la liste doit être développé ou non
    treeItemIsExpanded: YES,
    // treeItemChildren doit renvoyé une collection d'objet.
    // Ici on renvoie la liste des utilisateurs contenus dans un groupe 
    treeItemChildren: function(){
        return SourceListExample.store.find(SC.Query.local(SourceListExample.User,
        "groupId = {id}", {
            id: this.get('guid')
        }))
    }.property().cacheable()
});
SourceListExample.User = SC.Record.extend({
	name: (function(){
		return this.get('firstName') + " " + this.get('lastName');
	}).property('name'),
	lastName: SC.Record.attr(String),
	firstName: SC.Record.attr(String),
	groupId: SC.Record.attr(Number)
});

SproutCore permet l’utilisation de fixtures, données factices chargées au lancement de l’application. Les fichiers ont été générés précédemment. Editez leur contenu apps/source_list_example/fixtures/group_fixtures.js puis apps/source_list_example/fixtures/user_fixtures.js :

SourceListExample.Group.FIXTURES = [

	{ guid: 1,
	  name: "Développeurs" },

	{ guid: 2,
	  name: "Graphiste" },

];
SourceListExample.User.FIXTURES = [

	{ guid: 1,
	  firstName: "Michael",
	  lastName: "Scott",
	  groupId: 1 },

	{ guid: 2,
	  firstName: "Dwight",
	  lastName: "Schrute",
	  groupId: 1 },

	{ guid: 3,
	  firstName: "Jim",
	  lastName: "Halpert",
	  groupId: 1 },

	{ guid: 4,
	  firstName: "Pam",
	  lastName: "Beesly",
	  groupId: 2 },

	{ guid: 5,
	  firstName: "Ryan",
	  lastName: "Howard",
	  groupId: 2 }

];

Il  ne nous reste plus qu’a initialiser notre application avec notre contrôleur et nos modèles. Ouvrez le fichier apps/source_list_example/main.js

SourceListExample.main = function main() {
  SourceListExample.getPath('mainPage.mainPane').append() ;

	// Définition d'un objet racine qui va contenir le contenu de notre contrôleur
	var trunk = SC.Object.create({ 
		treeItemIsExpanded: YES, 
		treeItemChildren: function(){
			return SourceListExample.store.find(SourceListExample.Group);
		}.property()
	}); 
	// Affectation de l'objet racine à notre contrôleur
	SourceListExample.treeController.set('content', trunk);

} ;

function main() { SourceListExample.main();

Lancez le serveur de développement via la commande sc-server, puis ouvrez votre navigateur à l’adresse donnée, à priori : http://0.0.0.0:4020/source_list_example. Voici ce que vous devriez obtenir à l’écran :

Cette entrée a été publiée dans Tip, avec comme mot(s)-clef(s) , , . Vous pouvez la mettre en favoris avec ce permalien.