Permalink
Browse files

adjusted style, punctuaction a examples throughout view.textile

  • Loading branch information...
warp3d authored and etgryphon committed May 16, 2011
1 parent 4504697 commit 15f201864d2c9da09a18e4f9bca6e4b7642aa067
Showing with 54 additions and 50 deletions.
  1. +54 −50 source/views.textile
View
@@ -2,19 +2,21 @@ h2. Core View Concepts
The guide covers some of the core concepts of views in SproutCore. By referring to this guide, you will be able to:
-* Layout your views relative to their parent
-* Make your views dynamic with bindings
-* Change how your views render and update themselves
-* Handle events that occur over your view like a mouse click
+* Layout your views relative to their parent.
+* Make your views dynamic with bindings.
+* Change how your views render and update themselves.
+* Handle events that occur over your view like a mouse click.
endprologue.
h3. Introduction
After you've created your first SproutCore project, you'll notice the file +main_page.js+ in your resources folder. This is the main page that your app appends to the DOM in your +main+ function. Let's start by looking at what every SproutCore project starts with as it's main page:
-<javascript filename="apps/my_app/resources/main_page.js">
-MyApp.mainPage = SC.Page.design({
+INFO: The file +main_page.js+ is included into the application's resources folder when using <code>sc-init</code> without the <code>--template</cpde> param.
+
+<javascript filename="apps/app/resources/main_page.js">
+App.mainPage = SC.Page.design({
mainPane: SC.MainPane.design({
childViews: 'labelView'.w(),
labelView: SC.LabelView.design({
@@ -27,13 +29,13 @@ MyApp.mainPage = SC.Page.design({
});
</javascript>
-To understand what all of this means, we'll have to look at and understand what this boilerplate code does. +MyApp.mainPage+ is our main application page. Your application may end up having several "pages" or you may choose to swap content into and out of a single page. +MyApp.mainPage+ is an +SC.Page+ which works by lazily configuring itself. The views within a page are only awakened when you +get+ the page in the +main.js+ file:
+To understand what all of this means, we'll have to look at and understand what this boilerplate code does. +App.mainPage+ is our main application page. Your application may end up having several "pages" or you may choose to swap content into and out of a single page. +App.mainPage+ is an +SC.Page+ which works by lazily configuring itself. The views within a page are only awakened when you +get+ the page in the +main.js+ file:
-<javascript filename="in apps/my_app/main.js">
- MyApp.getPath('mainPage.mainPane').append();
+<javascript filename="in apps/app/main.js">
+App.getPath('mainPage.mainPane').append();
</javascript>
-+MyApp.mainPage.mainPane+ is an +SC.MainPane+ which is itself an +SC.Pane+. There will probably be many panes in your app because a pane is just like a regular view except that it doesn't need to live within a parent view. These can be anything from a pallette to a popup to a menu. In this case, our pane is an +SC.MainPane+ which automatically makes itself the main pane as soon as
++App.mainPage.mainPane+ is an +SC.MainPane+ which is itself an +SC.Pane+. There will probably be many panes in your app because a pane is just like a regular view except that it doesn't need to live within a parent view. These can be anything from a pallette to a popup to a menu. In this case, our pane is an +SC.MainPane+ which automatically makes itself the main pane as soon as
it's appended to the doument.
Our main pane is configured with only one +childView+, an +SC.LabelView+. SproutCore uses absolute positioning to layout it's views, and this label view is no different. Giving it a width and height allows us to center the label directly into the center of the page using +centerX+ and +centerY+ which specify how many pixels offset from the center we'd like the view.
@@ -44,8 +46,8 @@ h3. Laying Out Views on the Page
Let's say we wanted to make an address book. This address book would have a list of all your contacts that you could scroll through and see contact details such as phone numbers and addresses. Let's start the address book by starting an +SC.WorkspaceView+ which allows us to have a toolbar on the top and bottom and a view between those two toolbars:
-<javascript filename="apps/my_app/resources/main_page.js">
-MyApp.mainPage = SC.Page.design({
+<javascript filename="apps/app/resources/main_page.js">
+App.mainPage = SC.Page.design({
mainPane: SC.MainPane.design({
childViews: 'workspaceView'.w(),
workspaceView: SC.WorkspaceView.design({
@@ -55,11 +57,11 @@ MyApp.mainPage = SC.Page.design({
});
</javascript>
-NOTE: +design+ performs like +extend+ and may register with SproutCore's +designer+ framework, which is the basis of the interface builder, Greenhouse. You should never use +design+ outside of a page definition.
+NOTE: The class method +design+ performs like +extend+ and may register with SproutCore's +designer+ framework, which is the basis of the interface builder, Greenhouse. You should never use +design+ outside of a page definition.
We now have a nice toolbar on the top of the page, but we still don't have a list of any contacts. If we want a list on the right and details on the left, it sounds like +SC.SplitView+ is the perfect view to do that, so let's make that our +contentView+:
-<javascript filename="in apps/my_app/resoureces/main_page.js">
+<javascript filename="in apps/app/resoureces/main_page.js">
workspaceView: SC.WorkspaceView.design({
contentView: SC.SplitView.design({
dividerThickness: 1,
@@ -76,15 +78,15 @@ NOTE: When you use values less than 1 for dimensions in SproutCore they're inter
We're going to need to list our contacts, so let's do that to the left, with our details view to the right. For this, we could use +SC.ListView+ which is used for generic lists of stacked information where you know each list item's height. Fortunately, SproutCore includes +SC.SourceListView+ which not only looks great out of the box, but also provides the default behaviors of a source list:
-<javascript filename="in apps/my_app/resources/main_page.js">
+<javascript filename="in apps/app/resources/main_page.js">
topLeftView: SC.SourceListView.design({
content: ["Devin Torres", "Charles Jolley", "Peter Wagenet"]
})
</javascript>
We can then move on to the details of a contact, such as his name, phone phone number, and address. We can use +SC.LabelView+ for all three in our +bottomRightView+:
-<javascript filename="in apps/my_app/resources/main_page.js">
+<javascript filename="in apps/app/resources/main_page.js">
bottomRightView: SC.View.design({
childViews: 'contactDetails'.w(),
@@ -114,10 +116,10 @@ The labels are wrapped in +contactDetails+ so they can be cushioned from the edg
h3. Binding Views to Controllers
-Instead of having our source list content and our label values in our views, let's bind them to some controllers. We'll start by creating an SC.ArrayController for our list of contacts:
+Instead of having our source list content and our label values in our views, let's bind them to some controllers. We'll start by creating an <code>SC.ArrayController</code> for our list of contacts:
-<javascript filename="apps/my_app/controllers/contacts.js">
-MyApp.contactsController = SC.ArrayController.create({
+<javascript filename="apps/app/controllers/contacts.js">
+App.contactsController = SC.ArrayController.create({
allowsMultipleSelection: NO,
content: [
SC.Object.create({
@@ -126,12 +128,14 @@ MyApp.contactsController = SC.ArrayController.create({
address: "214 12th St. Austin, TX 78701",
website: 'http://www.linkedin.com/in/devintorres'
}),
+
SC.Object.create({
name: "Charles Jolley",
phone: "(555) 749-1585",
address: "378 16th St. Austin, TX 78701",
website: 'http://www.linkedin.com/in/charlesjolley'
}),
+
SC.Object.create({
name: "Peter Wagenet",
phone: "(555) 856-3750",
@@ -156,34 +160,34 @@ NOTE: An object controller will automatically detect if you have a single select
Now we can bind our source list to the +SC.ArrayController+ to get a dynamic list of contacts and individual contact selection support:
-<javascript filename="in apps/my_app/resources/main_page.js">
+<javascript filename="in apps/app/resources/main_page.js">
topLeftView: SC.SourceListView.design({
contentValueKey: 'name',
- contentBinding: 'MyApp.contactsController.content',
- selectionBinding: 'MyApp.contactsController.selection'
+ contentBinding: 'App.contactsController.content',
+ selectionBinding: 'App.contactsController.selection'
})
</javascript>
With the contacts selectable, the only thing missing is dynamic label values for the contact's name, phone, and address:
-<javascript filename="in apps/my_app/resources/main_page.js">
+<javascript filename="in apps/app/resources/main_page.js">
bottomRightView: SC.View.design({
layout: { top: 50, left: 50, bottom: 50, right: 20 },
childViews: 'nameLabel phoneLabel addressLabel'.w(),
nameLabel: SC.LabelView.design({
layout: { width: 500, height: 18 },
- valueBinding: SC.Binding.oneWay('MyApp.contactController.name')
+ valueBinding: SC.Binding.oneWay('App.contactController.name')
}),
phoneLabel: SC.LabelView.design({
layout: { top: 40, width: 500, height: 18 },
- valueBinding: SC.Binding.oneWay('MyApp.contactController.phone')
+ valueBinding: SC.Binding.oneWay('App.contactController.phone')
}),
addressLabel: SC.LabelView.design({
layout: { top: 80, width: 500, height: 500 },
- valueBinding: SC.Binding.oneWay('MyApp.contactController.address')
+ valueBinding: SC.Binding.oneWay('App.contactController.address')
})
})
</javascript>
@@ -198,15 +202,15 @@ SproutCore provides three ways to customize how your view looks. You can simply
h4. Using CSS to Style a View
-Let's make the interface a bit more visually appealing and user friendly by giving a usage hint when no contact has been selected yet. We ca create a generic view and add the class name +myapp-usage-hint+ to the +classNames+ array, and then a label view as a child to display the hint: Our +bottomRightView+ should now look like this:
+Let's make the interface a bit more visually appealing and user friendly by giving a usage hint when no contact has been selected yet. We ca create a generic view and add the class name +app-usage-hint+ to the +classNames+ array, and then a label view as a child to display the hint: Our +bottomRightView+ should now look like this:
-<javascript filename="in apps/my_app/resources/main_page.js">
+<javascript filename="in apps/app/resources/main_page.js">
bottomRightView: SC.View.design({
childViews: 'usageHint contactDetails'.w(),
usageHint: SC.View.design({
- classNames: 'myapp-usage-hint',
- isVisibleBinding: SC.Binding.not('MyApp.contactsController.hasSelection'),
+ classNames: 'app-usage-hint',
+ isVisibleBinding: SC.Binding.not('App.contactsController.hasSelection'),
childViews: [SC.LabelView.design({
layout: { width: 300, height: 22, centerX: 0, centerY: 0 },
@@ -223,30 +227,30 @@ bottomRightView: SC.View.design({
nameLabel: SC.LabelView.design({
layout: { width: 500, height: 18 },
- valueBinding: 'MyApp.contactController.name'
+ valueBinding: 'App.contactController.name'
}),
phoneLabel: SC.LabelView.design({
layout: { top: 40, width: 500, height: 18 },
- valueBinding: 'MyApp.contactController.phone'
+ valueBinding: 'App.contactController.phone'
}),
addressLabel: SC.LabelView.design({
layout: { top: 80, width: 500, height: 500 },
- valueBinding: 'MyApp.contactController.address'
+ valueBinding: 'App.contactController.address'
})
})
})
</javascript>
Right now it looks rather small, so let's add some style to it. Create a file in the +resources+ directory and name it +theme.css+:
-<css filename="apps/my_app/resources/theme.css">
-.myapp-usage-hint {
+<css filename="apps/app/resources/theme.css">
+.app-usage-hint {
background-color: #eee;
}
-.myapp-usage-hint h1 {
+.app-usage-hint h1 {
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", inherit;
font-size: 28px !important;
line-height: 20px !important;
@@ -256,7 +260,7 @@ Right now it looks rather small, so let's add some style to it. Create a file in
Now we have nice looking instructions for when a user first starts using the app. You can add as many class names to +classNames+ as you want for any view.
-h4. The +render+ and +update+ Methods
+h4. The render and update Methods
The +render+ method is used to generate the view's HTML and is called whenever the view first renders itself and any subsequent updates to the view can be handled by an +update+ method after that.
@@ -312,10 +316,10 @@ CreepyApp.CharlesJolleyView = SC.View.extend({
})
</javascript>
-Say we wanted to make the name of the contact bigger in the details. To do this, let's create a custom view called +MyApp.ContactNameView+ that will put the contact name in an h1 tag:
+Say we wanted to make the name of the contact bigger in the details. To do this, let's create a custom view called +App.ContactNameView+ that will put the contact name in an h1 tag:
-<javascript filename="apps/my_app/views/contact_name.js">
-MyApp.ContactNameView = SC.View.extend({
+<javascript filename="apps/app/views/contact_name.js">
+App.ContactNameView = SC.View.extend({
displayProperties: ['value'],
render: function (context) {
context.push('<h1>', this.get('value'), '</h1>');
@@ -330,8 +334,8 @@ h4. Render Delegates
Render delegates are an easy way to manage theming your apps. You can create a render delegate to manage the rendering of your views for you and add it to the theme you're using. Render delegates also have a +render+ and +update+ method, but their first argument is the +dataSource+, or the view delegating to them. Let's recreate the last scenario using an +SC.RenderDelegate+ that we're going to create in +render_delegates/contact_name.js+:
-<javascript filename="apps/my_app/render_delegates/contact_name.js">
-MyApp.MyTheme.contactNameRenderDelegate = SC.RenderDelegate.create({
+<javascript filename="apps/app/render_delegates/contact_name.js">
+App.MyTheme.contactNameRenderDelegate = SC.RenderDelegate.create({
render: function (dataSource, context) {
context.push('<h1>', dataSource.get('value'), '</h1>');
},
@@ -343,8 +347,8 @@ MyApp.MyTheme.contactNameRenderDelegate = SC.RenderDelegate.create({
Now we have to tell our view to use our new render delegate to draw itself:
-<javascript filename="apps/my_app/views/contact_name.js">
-MyApp.ContactNameView = SC.View.extend({
+<javascript filename="apps/app/views/contact_name.js">
+App.ContactNameView = SC.View.extend({
displayProperties: ['value'],
renderDelegateName: 'contactNameRenderDelegate'
});
@@ -354,10 +358,10 @@ TIP: For a more detailed overview of themeing see "Theming Your App":theming_app
h3. View Events
-A SproutCore view hierarchy can be viewed like a pond, if the water is touched it ripples outwards affecting all the water around it, or in our case, all the parent views. +SC.View+ extends from +SC.Responder+, inheriting the ability to react to DOM events such as +mouseDown+ and +mouseEntered+. Let's highlight the contact name when it's being hovered over and take the user to the contact's website if it's clicked:
+A SproutCore view hierarchy can be viewed like a pond, if the water is touched it ripples outwards affecting all the water around it, or in our case, all the parent views. +SC.View+ extends +SC.Responder+, inheriting the ability to react to DOM events such as +mouseDown+ and +mouseEntered+. Let's highlight the contact name when it's being hovered over and take the user to the contact's website if it's clicked:
-<javascript filename="apps/my_app/views/contact_name_view.js">
-MyApp.ContactNameView = SC.View.extend({
+<javascript filename="apps/app/views/contact_name_view.js">
+App.ContactNameView = SC.View.extend({
displayProperties: ['value'],
renderDelegateName: 'contactNameRenderDelegate',
mouseEntered: function () {
@@ -373,17 +377,17 @@ MyApp.ContactNameView = SC.View.extend({
return YES;
},
mouseDown: function (evt) {
- MyApp.openWebsite();
+ App.openWebsite();
return YES;
}
});
</javascript>
And in +core.js+:
-<javascript filename="in apps/my_app/core.js">
+<javascript filename="in apps/app/core.js">
openWebsite: function () {
- var website = MyApp.contactController.get('website');
+ var website = App.contactController.get('website');
window.open(website);
}
</javascript>

0 comments on commit 15f2018

Please sign in to comment.