addded cookbook

This commit is contained in:
Misko Hevery 2011-02-01 10:01:02 -08:00
parent b6a01bd27d
commit 245b60d69a
16 changed files with 426 additions and 24 deletions

4
docs/cookbook.buzz.ngdoc Normal file
View file

@ -0,0 +1,4 @@
@workInProgress
@ngdoc overview
@name Cookbook: Resources - Buzz Demo
@description

View file

@ -0,0 +1,4 @@
@workInProgress
@ngdoc overview
@name Cookbook: Deep Linking
@description

85
docs/cookbook.form.ngdoc Normal file
View file

@ -0,0 +1,85 @@
@workInProgress
@ngdoc overview
@name Cookbook: Form
@description
A web application's main purpose is to present and gather data. For this reason <angular/> strives to make both of these operations trivial. This example shows off how you can build a simple form to allow a user to enter data.
<doc:example>
<doc:source>
<script>
function FormController(){
this.user = {
name: 'John Smith',
address:{line1: '123 Main St.', city:'Anytown', state:'AA', zip:'12345'},
contacts:[{type:'phone', value:'1(234) 555-1212'}]
};
this.state = /^\w\w$/;
this.zip = /^\d\d\d\d\d$/;
}
</script>
<div ng:controller="FormController" class="example">
<label>Name:</label><br/>
<input type="text" name="user.name" ng:required/> <br/><br/>
<label>Address:</label><br/>
<input type="text" name="user.address.line1" size="33" ng:required/> <br/>
<input type="text" name="user.address.city" size="12" ng:required/>,
<input type="text" name="user.address.state" size="2" ng:required ng:validate="regexp:state"/>
<input type="text" name="user.address.zip" size="5" ng:required ng:validate="regexp:zip"/><br/><br/>
<label>Phone:</label>
[ <a href="" ng:click="user.contacts.$add()">add</a> ]
<div ng:repeat="contact in user.contacts">
<select name="contact.type">
<option>email</option>
<option>phone</option>
<option>pager</option>
<option>IM</option>
</select>
<input type="text" name="contact.value" ng:required/>
[ <a href="" ng:click="user.contacts.$remove(contact)">X</a> ]
</div>
<hr/>
Debug View:
<pre>user={{user}}</pre>
</div>
</doc:source>
<doc:scenario>
it('should show debug', function(){
expect(binding('user')).toMatch(/John Smith/);
});
iit('should add contact', function(){
using('.example').element('a:contains(add)').click();
using('.example div:last').input('contact.value').enter('you@example.org');
expect(binding('user')).toMatch(/\(234\) 555\-1212/);
expect(binding('user')).toMatch(/you@example.org/);
});
iit('should remove contact', function(){
});
iit('should validate zip', function(){
});
iit('should validate state', function(){
});
</doc:scenario>
</doc:example>
# Things to notice
* The user data model is initialized {@link angular.ng:controller controller} and is available in
the {@link angular.scope scope} with the initial data.
* For debugging purposes we have included a debug view of the model to better understand what
is going on.
* The {@link angular.widget.HTML input widgets} simply refer to the model and are auto bound.
* The inputs {@link angular.validator validate}. (Try leaving them blank or entering non digits
in the zip field)
* In your application you can simply read from or write to the model and the form will be updated.
* By clicking the 'add' link you are adding new items into the `user.contacts` array which are then
reflected in the view.

View file

@ -0,0 +1,4 @@
@workInProgress
@ngdoc overview
@name Cookbook: Advanced Form
@description

View file

@ -0,0 +1,31 @@
@workInProgress
@ngdoc overview
@name Cookbook: Hello World
@description
<doc:example>
<doc:source>
Your name: <input type="text" name="name" value="World"/>
<hr/>
Hello {{name}}!
</doc:source>
<doc:scenario>
iit('should change the binding when user enters text', function(){
expect(binding('name')).toEqual('World');
input('name').enter('angular');
expect(binding('name')).toEqual('angular');
});
</doc:scenario>
</doc:example>
# Things to notice
Take a look through the source and note:
* The script tag that {@link guide.bootstrap bootstraps} the angular environment.
* The text {@link angular.widget.HTML input widget} which is bound to the greeting name text.
* No need for listener registration and event firing on change events.
* The implicit presence of the `name` variable which is in the root {@link angular.scope scope}.
* The double curly brace `{{markup}}`, which binds the name variable to the greeting text.
* The concept of {@link guide.data-binding data binding}, which reflects any changes to the
input field in the greeting text.

4
docs/cookbook.mvc.ngdoc Normal file
View file

@ -0,0 +1,4 @@
@workInProgress
@ngdoc overview
@name Cookbook: MVC
@description

60
docs/cookbook.ngdoc Normal file
View file

@ -0,0 +1,60 @@
@workInProgress
@ngdoc overview
@name Cookbook
@description
Welcome to the angular cookbook. Here we will show you typical uses of angular by example.
# Hello World
{@link cookbook.helloworld Hello World}: The simplest possible application that demonstrates the
classic Hello World!
# Basic Form
{@link cookbook.form Basic Form}: Displaying forms to the user for editing is the bread and butter
of web applications. Angular makes forms easy through bidirectional data binding.
# Advanced Form
{@link cookbook.formadvanced Advanced Form}: Taking the form example to the next level and
providing advanced features such as dirty detection, form reverting and submit disabling if
validation errors exist.
# Model View Controller
{@link cookbook.mvc MVC}: Tic-Tac-Toe: Model View Controller (MVC) is a time-tested design pattern
to separate the behavior (JavaScript controller) from the presentation (HTML view). This
separation aids in maintainability and testability of your project.
# Multi-page App and Deep Linking
{@link cookbook.deeplinking Deep Linking}: An AJAX application never navigates away from the
first page it loads. Instead, it changes the DOM of its single page. Eliminating full-page reloads
is what makes AJAX apps responsive, but it creates a problem in that apps with a single URL
prevent you from emailing links to a particular screen within your application.
Deep linking tries to solve this by changing the URL anchor without reloading a page, thus
allowing you to send links to specific screens in your app.
# Services
{@link angular.service Services}: Services are long lived objects in your applications that are
available across controllers. A collection of useful services are pre-bundled with angular but you
will likely add your own. Services are initialized using dependency injection, which resolves the
order of initialization. This safeguards you from the perils of global state (a common way to
implement long lived objects).
# External Resources
{@link cookbook.buzz Resources}: Web applications must be able to communicate with the external
services to get and update data. Resources are the abstractions of external URLs which are
specially tailored to angular data binding.

81
docs/fag.ngdoc Normal file
View file

@ -0,0 +1,81 @@
@workInProgress
@ngdoc overview
@name FAQ
@description
#FAQ
### Why is this project called "angular"? Why is the namespace called "ng"?
Because HTML has angular brackets and "ng" sounds like "angular".
### Is <angular/> an HTML5 tag?
No, <angular/> is not an HTML5 tag. angular is an orthogonal project to HTML5; you can use the two
together.
### Is angular a {library, framework, DOM manipulation library, widget library, native plugin}?
No, angular is none of these. You don't call its functions, it does not call your functions,
it does not provide a way to manipulate DOM, but does provide primitives to create UI projections
of your data. There are lots of existing widget libraries which you can integrate with angular.
It is 100% JavaScript, 100% client side and compatible with both desktop and mobile browsers.
### Do I need to worry about security holes in angular?
Like with any technology, angular is not impervious to attack. angular does, however, provide
built-in protection from basic security holes including cross-site scripting and HTML injection
attacks. angular does round-trip escaping on all strings for you.
### Can I download the source, build, and host the angular environment locally?
Yes. See instructions in {@link guide.downloading downloading}.
### Is angular a templating system?
At the highest level, angular does look like a just another templating system. But there is one
important reason why angular templating system is different and makes it very good fit for
application development: bidirectional data binding. The template is compiled on the browser and
the compilation step produces a live view. This means you, the developer, don't need to write
code to constantly sync the view with the model and the model with the view as in other
templating systems.
### What browsers does angular work with?
Webkit-based browsers (Safari, Chrome, iPhone, Android, WebOS, BlackBerry 6), Firefox, IE6 and
above. Note that CSS only works on IE7 and above.
### What's angular's performance like?
angular takes ~300ms to load, render, and compile. In Chrome it uses about 2-5MB of memory. Your
app's performance will vary depending on how many bindings you use.
### How big is the angular bootstrap JS file that I need to include?
The size of the library itself is < 50KB compressed and obfuscated.
### Can I use the open-source Closure Library with angular?
Yes, you can use widgets from the {@link http://code.google.com/closure/library Closure Library}
in angular.
### Does angular use the jQuery library?
Yes, angular uses {@link http://jquery.com/ jQuery}, the open source DOM manipulation library.
If jQuery is not present in your script path, angular falls back on its own implementation of
{@link angular.element jQuery lite}. If jQuery is present in the path, angular uses it to
manipulate the DOM.
### What is testability like in angular?
Very testable. It has an integrated dependency injection framework. See
{@link angular.service service} for details.
### How can I learn more about angular?
Watch the July 28, 2010 talk
"{@link http://www.youtube.com/watch?v=elvcgVSynRg| Angular: A Radically Different Way of Building AJAX Apps}".
### How is angular licensed?
The MIT License.

BIN
docs/img/angular_parts.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
docs/img/helloworld.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -515,7 +515,8 @@ function metadata(docs){
}
var KEYWORD_PRIORITY = {
'.guide': 1,
'.started': 1,
'.guide': 2,
'.guide.overview': 1,
'.angular': 7,
'.angular.Array': 7,

View file

@ -29,17 +29,22 @@
scenario = element.find('doc\\:scenario').eq(0);
var code = indent(exampleSrc);
var tabs = angular.element(
'<ul class="doc-example">' +
'<li class="doc-example-heading"><h3>Source</h3></li>' +
'<li class="doc-example-source" ng:non-bindable>' +
'<pre class="brush: js; html-script: true; highlight: [' +
code.hilite + ']; toolbar: false;"></pre></li>' +
'<li class="doc-example-heading"><h3>Live Preview</h3></li>' +
'<li class="doc-example-live">' + exampleSrc +'</li>' +
'<li class="doc-example-heading"><h3>Scenario Test</h3></li>' +
'<li class="doc-example-scenario"><pre class="brush: js">' + scenario.text() + '</pre></li>' +
'</ul>');
var tabHtml =
'<ul class="doc-example">' +
'<li class="doc-example-heading"><h3>Source</h3></li>' +
'<li class="doc-example-source" ng:non-bindable>' +
'<pre class="brush: js; html-script: true; highlight: [' +
code.hilite + ']; toolbar: false;"></pre></li>' +
'<li class="doc-example-heading"><h3>Live Preview</h3></li>' +
'<li class="doc-example-live">' + exampleSrc +'</li>';
if (scenario.text()) {
tabHtml +=
'<li class="doc-example-heading"><h3>Scenario Test</h3></li>' +
'<li class="doc-example-scenario"><pre class="brush: js">' + scenario.text() + '</pre></li>';
}
tabHtml +=
'</ul>';
var tabs = angular.element(tabHtml);
tabs.find('li.doc-example-source > pre').text(HTML_TEMPLATE.replace('_HTML_SOURCE_', code.html));

View file

@ -2,26 +2,27 @@ DocsController.$inject = ['$location', '$browser', '$window'];
function DocsController($location, $browser, $window) {
this.pages = NG_PAGES;
window.$root = this.$root;
this.$location = $location;
this.$watch('$location.hashPath', function(hashPath){
hashPath = hashPath || '!angular';
if (hashPath.match(/^!/)) {
this.partialId = hashPath.substring(1);
this.partialTitle = (angular.Array.filter(NG_PAGES, {id:this.partialId})[0]||{}).name;
}
});
this.getUrl = function(page){
return '#!' + page.id;
};
this.getCurrentPartial = function(){
return './' + this.getTitle() + '.html';
};
this.getTitle = function(){
var hashPath = $location.hashPath || '!angular';
if (hashPath.match(/^!/)) {
this.partialTitle = hashPath.substring(1);
}
return this.partialTitle;
return './' + this.partialId + '.html';
};
this.getClass = function(page) {
var depth = page.depth,
cssClass = 'level-' + depth + (page.name == this.getTitle() ? ' selected' : '');
cssClass = 'level-' + depth + (page.name == this.partialId ? ' selected' : '');
if (depth == 1 && page.type !== 'overview') cssClass += ' level-angular';

View file

@ -3,7 +3,7 @@
xmlns:doc="http://docs.angularjs.org/"
ng:controller="DocsController">
<head>
<title ng:bind-template="&lt;angular/&gt;: {{getTitle()}}">&lt;angular/&gt;</title>
<title ng:bind-template="&lt;angular/&gt;: {{partialTitle}}">&lt;angular/&gt;</title>
<meta name="fragment" content="!">
@ -25,7 +25,7 @@
<body style="display:none;" ng:show="true">
<div id="header">
<h1>
<span class="main-title">{{getTitle()}}</span>
<span class="main-title">{{partialTitle}}</span>
<a href="#" tabindex="0"><span class="angular">&lt;angular/&gt;</span> Docs</a>
</h1>
</div>

122
docs/started.ngdoc Normal file
View file

@ -0,0 +1,122 @@
@workInProgress
@ngdoc overview
@name Getting Started
@description
# Hello World
The easiest way to get started with angular is to create a basic Hello World app.
# Step 1
In your favorite text editor, create a file called helloworld.html. Copy and paste the following
contents into the file:
<doc:example>
<doc:source>
Hello {{'World'}}!
</doc:source>
</doc:example>
# Step 2
<img class="right" src="img/helloworld.png"/>
Navigate to the file helloworld.html in your browser. The page should look like the screenshot
below:
That's it! Now take another look at helloworld.html. Here's what's going on behind the scenes:
<pre>
<html xmlns:ng="http://angularjs.org">
</pre>
Defines the namespace `ng`, which represents the URL `http://angularjs.org`. You must define the
`ng` namespace in your application so the browser understands angular directives like
`ng:autobind`.
<pre>
<script type="text/javascript" src="http://code.angularjs.org/angular-?.?.?.min.js" ng:autobind></script>
</pre>
Sets the `src` attribute of the script tag to `http://code.angularjs.org/angular-?.?.?.min.js` to
bootstrap to the angular environment. Uses the `ng:autobind` attribute to compile and manage the
whole HTML document. The compilation happens in the page's onLoad handler.
<pre>
Hello {{'World'}}!
</pre>
This is the template that describes how this element is displayed in the UI.
Uses the double curly brace markup (`{{}}`) to bind an expression to the greeting text. In this
case the expression is the string literal 'World'.
# Step 3
For a more advanced Hello World example that demonstrates angular's two-way data binding, edit
helloworld.html and replace the contents of the `<body/>` with:
<doc:example>
<doc:source>
Your name: <input type="text" name="yourname" value="World"/>
<hr/>
Hello {{yourname}}!
</doc:source>
</doc:example>
<img class="right" src="img/helloworld_2way.png"/>
These are the changes to note:
* The text input widget is bound to the text stored by the name variable.
* The name variable is implicit in the root scope.
* You did not need to explicitly register an event listener or define an event handler for events.
Now refresh the `helloworld.html` page in your browser. Your screen should now look like this:
Type your name into the input box and notice the immediate change to the displayed greeting. This
example demonstrates the concept of angular's two-way data binding; any changes to the input field
are immediately reflected in the greeting text.
# Anatomy of an angular app
These are the 3 parts of an angular app and how they map to the Model-View-Controller design pattern:
# Template
Templates, which you write in HTML and CSS, are the View. You add elements, attributes, and markup
to HTML, which are instructions to the angular compiler. These instructions are fully extensible,
meaning that you can build your own declarative language with angular.
# Application Logic and Behavior
Application Logic and Behavior, which you define in JavaScript, are the Controllers. Unlike
normal AJAX applications, you don't need to write additional listeners or DOM manipulators in
angular because they are built-in. This makes your application logic very easy to write, test,
maintain, and understand.
# Scope
<img class="right" src="img/angular_parts.png"/>
Scope, which is a JavaScript object that has the ability to watch for changes and get notified of
them, is the Model. You typically don't need to write much, if any, additional JavaScript to
define your model.
Additionally, angular comes with a set of Services, which have the following properties:
* Useful for building web applications.
* You can extend the services and add application-specific behavior to them.
* Examples include Dependency-Injection, XHR, caching, URL routing, and browser abstraction.
The following illustrates each part of an angular application and how they work together:
# Where to go next
For more hands-on examples of using angular, including more source code that you can copy and
paste into your own page, take a look through {@link cookbook}.
For explanations of the concepts described in this example, see {@link guide.bootstrap bootstrap},
{@link guide.template template}, {@link angular.widget.HTML input}, {@link angula.scope scope},
{@link angular.markup markup}, and {@link guide.data-binding data binding}.
To read about the HTML compiler and the compilation process, see {@link guide.compiler compiler}.
For more angular concepts, see the {@link guide Developer Guide}.