<?xml version="1.0" encoding="UTF-8"?>
<wiki>
  <body>&lt;h2&gt;SproutCore Controller Classes and Their Differences&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;SC.ObjectController:&lt;/strong&gt;  An ObjectController gives you a simple way to manage the editing state of an object. You can use an ObjectController instance as a &amp;#8220;proxy&amp;#8221; for your model objects.  For example, if you create a Record object called &amp;#8220;Albums.Vinyl&amp;#8221; and plan on allowing your application to edit the properties of your objects, it would be a good idea to create an ObjectController and call it &amp;#8220;Albums.vinylController&amp;#8221; to be more precise. This object could become the receptacle for the properties of whichever Vinyl is currently selected on a web page, by setting the contentBinding property.   For example, you could setup your object controller to show the selected vinyl by doing:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;
Albums.vinylController = SC.ObjectController.create({
  contentBinding: &quot;Albums.vinylsListController.selection&quot;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An ObjectController can control any class extending SC.Object.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;SC.ArrayController:&lt;/strong&gt;  An Array Controller provides a way to project the contents of an array out to a view. You can use this object any place you might use an array. This will probably be the Controller that is most useful to you and gives you the most control over its objects, with the least &amp;#8220;overhead.&amp;#8221; When in doubt, use this one.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An ArrayController expects to work with an object that implements the SC.Array mixin.  All built-in JavaScript Arrays implement SC.Array.  Other classes that are not native Arrays but implement SC.Array are called &amp;#8220;array-like&amp;#8221; objects.  Set the content property of your ArrayController to the array or array-like object you want to control.  For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
  var recordArray = Albums.Vinyl.findAll() ;
  Albums.masterController.set('content', recordArray) ;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To manage items in your array, you should bind views to the &amp;#8220;arrangedObjects&amp;#8221; property.  This property represents the content array in a form usable by the CollectionViews in your UI. (i.e. SC.ListView, SC.GridView, etc.)  ArrayControllers also implement a &amp;#8220;selection&amp;#8221; property which is an array of your currently selected items.  Bind the selection property of your collection views to the selection property of your array controller.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;SC.CollectionController:&lt;/strong&gt; A CollectionController works just like an ArrayController except that it includes support for working with SC.Collection objects. An SC.Collection object is like a &amp;#8220;smart group&amp;#8221; in that it updates its contents automatically based on preset filters you have designated. In Database design terms, this might be thought of as a table-view, while an ArrayController would be the table itself. So for instance, when you want to delete a &amp;#8220;row&amp;#8221; in your db table, you would not try to delete it from the view, you would delete it from the actual table.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A CollectionController expects to be working with an SC.Collection object or something extending this class, as its &amp;#8220;content&amp;#8221; property.  For example :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
  var recordCollection = Albums.Vinyl.collection() ;
  Albums.masterController.set('content', recordCollection) ;
  recordCollection.refresh() ;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;SC.Controller:&lt;/strong&gt;  The controller base class provides some common functions you will need for controllers in your applications, especially related to maintaining an editing context. In general &lt;strong&gt;you will not use this class&lt;/strong&gt;, but you can use a subclass such as ObjectController, CollectionController, or ArrayController.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Basic example of &lt;span class=&quot;caps&quot;&gt;CRUD&lt;/span&gt; application using Controller classes&lt;/h2&gt;
&lt;p&gt;Lets say you are creating a basic web application to track your vinyl collection. You would like to be able to manage a list of records, find individual albums by name, add, delete, and edit metadata about albums, such as artist name, year released, number of tracks, and condition of the vinyl. These basic tasks &amp;#8211; (Create, Read, Update, Delete) &amp;#8211; are basic to most web applications, so a lot of this is already done for you in SproutCore.&lt;/p&gt;
&lt;p&gt;Your new application is going to be called:  &amp;#8220;Albums&amp;#8221;&lt;br /&gt;
And it will track an unlimited amount of Record objects called &amp;#8220;Vinyl&amp;#8221;&lt;/p&gt;
&lt;p&gt;To create your application, do:&lt;br /&gt;
&lt;pre class=&quot;console&quot;&gt;sc-init albums&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Then, to create your model, do:&lt;br /&gt;
&lt;pre class=&quot;console&quot;&gt;sc-gen model albums/vinyl&lt;/pre&gt;&lt;br /&gt;
This creates a file for your model &lt;code&gt;clients/albums/models/vinyl.js&lt;/code&gt;, a file to create fixtures (instances of your model that will load initially without needing a database and that are helpful for experimentation purposes) &lt;code&gt;clients/albums/fixtures/vinyl.js&lt;/code&gt;, and a file to define tests for your model &lt;code&gt;clients/albums/tests/models/vinyl.rhtml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To make sure all of your objects that you will create are distinct from anyone else&amp;#8217;s objects, the &lt;code&gt;sc-gen model&lt;/code&gt; command creates a namespace. (See example code in &lt;code&gt;core.js&lt;/code&gt;:  &lt;code&gt;server: SC.Server.create({ prefix: ['Albums'] })&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;And since the Vinyl class is part of the Albums application, the syntax generated for you to create the namespace is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Albums.Vinyl = SC.Record.extend(
/** @scope Albums.Vinyl.prototype */ {
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When viewing your albums, it would be reasonable to want to sort them by various criteria, such as title, artist, year, etc. So this need suggests that a Collection object would be the best way to store them, and a CollectionController would be the best way to manage this Collection object.&lt;/p&gt;
&lt;p&gt;Your main controller will be called vinylController, and you can create it with:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;sc-gen controller albums/vinylController SC.CollectionController&lt;/pre&gt;
&lt;p&gt;This creates a file for your controller &lt;code&gt;clients/albums/controllers/vinyl.js&lt;/code&gt; and a file to define for your controller &lt;code&gt;clients/albums/tests/controllers/vinyl_controller.rhtml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;vinyl.js&lt;/code&gt;, you should see the line:&lt;br /&gt;
&lt;code&gt;Albums.vinylController = SC.CollectionController.create(&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Seeing What You Have&lt;/h3&gt;
&lt;p&gt;Once these classes are created, you could create a custom view object ([[Creating Custom Views]]) to see them, or just use one of the many SC.View derived classes already created for you. Either way, you will call these classes into action on your &lt;code&gt;body.rhtml&lt;/code&gt; page by using view helper syntax.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;div class=&quot;recordList&quot;&amp;gt;
&amp;lt;% scroll_view :record_list_scroll_view, :height =&amp;gt; 200 do %&amp;gt;
  &amp;lt;%= list_view :record_list,
    :content_value_key =&amp;gt; 'album_name',
    :content_value_editable =&amp;gt; true,
    :can_reorder_content =&amp;gt; true,
    :can_delete_content =&amp;gt; true,
    :bind =&amp;gt; {
      :content =&amp;gt; &quot;Albums.vinylController.arrangedObjects&quot;,
      :selection =&amp;gt; &quot;Albums.vinylController.selection&quot;
    } %&amp;gt;

&amp;lt;% end %&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One way to think about SC.Collection is that it&amp;#8217;s like a &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; query.  But unlike a &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; query, it&amp;#8217;s more like a &amp;#8220;smart&amp;#8221; query (using iTunes   &lt;br /&gt;
lingo) that will update whenever the contents of SC.Store change.&lt;/p&gt;
&lt;h1&gt;Related Links&lt;/h1&gt;
&lt;h1&gt;Comments&lt;/h1&gt;
&lt;p&gt;In general, this is good, and is what makes it so easy to bind your model layer to your controllers, and your controllers to your views.&lt;/p&gt;
&lt;p&gt;However, removing a record from a collection &lt;strong&gt;without doing anything else&lt;/strong&gt; doesn&amp;#8217;t make much sense. A collection is a smart query, not some arbitrary list, so the only way to change what is in the collection is to change the objects the query is working against. Because of this, some of you have discovered that you need to &amp;#8220;remove&amp;#8221; the record from the store to remove it from the collection. Hopefully now, it should make sense why that works, and why it&amp;#8217;s not a good solution.&lt;/p&gt;
&lt;p&gt;The real solution is easy. If you need to present an arbitrary list of records to your controller (and from there on up to your views), be easy on yourself and &lt;strong&gt;do not use a smart query to hold them&lt;/strong&gt; (e.g. do not use SC.Collection).&lt;/p&gt;
&lt;p&gt;Instead, use a normal, plain jane, vanilla JavaScript array. It&amp;#8217;ll stay &amp;#8220;in order&amp;#8221; automatically. You can add (and remove) records, of any type, at any time, and as long as you use the methods in SC.Array to do so, your controllers and views will update as expected.  &lt;em&gt;-onitunes&lt;/em&gt;&lt;/p&gt;</body>
  <created-at type="datetime">2008-08-18T13:19:58-07:00</created-at>
  <id type="integer">46585</id>
  <permalink>keeping-control</permalink>
  <repository-id type="integer">18944</repository-id>
  <title>Keeping Control</title>
  <updated-at type="datetime">2008-08-20T13:41:52-07:00</updated-at>
  <user-id type="integer">17276</user-id>
</wiki>
