Update everything
This commit is contained in:
parent
bf368181a4
commit
72a485d6e8
319 changed files with 67958 additions and 13948 deletions
139
lib/angular/docs/partials/cookbook/advancedform.html
Normal file
139
lib/angular/docs/partials/cookbook/advancedform.html
Normal file
|
@ -0,0 +1,139 @@
|
|||
<h1><code ng:non-bindable=""></code>
|
||||
<span class="hint"></span>
|
||||
</h1>
|
||||
<div><p>Here we extend the basic form example to include common features such as reverting, dirty state
|
||||
detection, and preventing invalid form submission.</p>
|
||||
|
||||
<h3>Source</h3>
|
||||
<div source-edit="" source-edit-deps="angular.js script.js" source-edit-html="index.html" source-edit-css="" source-edit-js="script.js" source-edit-unit="" source-edit-scenario="scenario.js"></div>
|
||||
<div class="tabbable"><div class="tab-pane" title="index.html">
|
||||
<pre class="prettyprint linenums" ng-set-text="index.html" ng-html-wrap=" angular.js script.js"></pre>
|
||||
<script type="text/ng-template" id="index.html">
|
||||
|
||||
<div ng-controller="UserForm">
|
||||
|
||||
<form name="myForm">
|
||||
|
||||
<label>Name:</label><br/>
|
||||
<input type="text" ng-model="form.name" required/> <br/><br/>
|
||||
|
||||
<label>Address:</label> <br/>
|
||||
<input type="text" ng-model="form.address.line1" size="33" required/> <br/>
|
||||
<input type="text" ng-model="form.address.city" size="12" required/>,
|
||||
<input type="text" ng-model="form.address.state" size="2"
|
||||
ng-pattern="state" required/>
|
||||
<input type="text" ng-model="form.address.zip" size="5"
|
||||
ng-pattern="zip" required/><br/><br/>
|
||||
|
||||
<label>Contacts:</label>
|
||||
[ <a href="" ng-click="addContact()">add</a> ]
|
||||
<div ng-repeat="contact in form.contacts">
|
||||
<select ng-model="contact.type">
|
||||
<option>email</option>
|
||||
<option>phone</option>
|
||||
<option>pager</option>
|
||||
<option>IM</option>
|
||||
</select>
|
||||
<input type="text" ng-model="contact.value" required/>
|
||||
[ <a href="" ng-click="removeContact(contact)">X</a> ]
|
||||
</div>
|
||||
<button ng-click="cancel()" ng-disabled="isCancelDisabled()">Cancel</button>
|
||||
<button ng-click="save()" ng-disabled="isSaveDisabled()">Save</button>
|
||||
</form>
|
||||
|
||||
<hr/>
|
||||
Debug View:
|
||||
<pre>form={{form}}</pre>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="script.js">
|
||||
<pre class="prettyprint linenums" ng-set-text="script.js"></pre>
|
||||
<script type="text/ng-template" id="script.js">
|
||||
function UserForm($scope) {
|
||||
var master = {
|
||||
name: 'John Smith',
|
||||
address:{
|
||||
line1: '123 Main St.',
|
||||
city:'Anytown',
|
||||
state:'AA',
|
||||
zip:'12345'
|
||||
},
|
||||
contacts:[
|
||||
{type:'phone', value:'1(234) 555-1212'}
|
||||
]
|
||||
};
|
||||
|
||||
$scope.state = /^\w\w$/;
|
||||
$scope.zip = /^\d\d\d\d\d$/;
|
||||
|
||||
$scope.cancel = function() {
|
||||
$scope.form = angular.copy(master);
|
||||
};
|
||||
|
||||
$scope.save = function() {
|
||||
master = $scope.form;
|
||||
$scope.cancel();
|
||||
};
|
||||
|
||||
$scope.addContact = function() {
|
||||
$scope.form.contacts.push({type:'', value:''});
|
||||
};
|
||||
|
||||
$scope.removeContact = function(contact) {
|
||||
var contacts = $scope.form.contacts;
|
||||
for (var i = 0, ii = contacts.length; i < ii; i++) {
|
||||
if (contact === contacts[i]) {
|
||||
contacts.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.isCancelDisabled = function() {
|
||||
return angular.equals(master, $scope.form);
|
||||
};
|
||||
|
||||
$scope.isSaveDisabled = function() {
|
||||
return $scope.myForm.$invalid || angular.equals(master, $scope.form);
|
||||
};
|
||||
|
||||
$scope.cancel();
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="End to end test">
|
||||
<pre class="prettyprint linenums" ng-set-text="scenario.js"></pre>
|
||||
<script type="text/ng-template" id="scenario.js">
|
||||
it('should enable save button', function() {
|
||||
expect(element(':button:contains(Save)').attr('disabled')).toBeTruthy();
|
||||
input('form.name').enter('');
|
||||
expect(element(':button:contains(Save)').attr('disabled')).toBeTruthy();
|
||||
input('form.name').enter('change');
|
||||
expect(element(':button:contains(Save)').attr('disabled')).toBeFalsy();
|
||||
element(':button:contains(Save)').click();
|
||||
expect(element(':button:contains(Save)').attr('disabled')).toBeTruthy();
|
||||
});
|
||||
it('should enable cancel button', function() {
|
||||
expect(element(':button:contains(Cancel)').attr('disabled')).toBeTruthy();
|
||||
input('form.name').enter('change');
|
||||
expect(element(':button:contains(Cancel)').attr('disabled')).toBeFalsy();
|
||||
element(':button:contains(Cancel)').click();
|
||||
expect(element(':button:contains(Cancel)').attr('disabled')).toBeTruthy();
|
||||
expect(element(':input[ng\\:model="form.name"]').val()).toEqual('John Smith');
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div><h3>Demo</h3>
|
||||
<div class="well doc-example-live" ng-embed-app="" ng-set-html="index.html" ng-eval-javascript="script.js"></div>
|
||||
|
||||
<h2>Things to notice</h2>
|
||||
|
||||
<ul>
|
||||
<li>Cancel & save buttons are only enabled if the form is dirty — there is something to cancel or
|
||||
save.</li>
|
||||
<li>Save button is only enabled if there are no validation errors on the form.</li>
|
||||
<li>Cancel reverts the form changes back to original state.</li>
|
||||
<li>Save updates the internal model of the form.</li>
|
||||
<li>Debug view shows the two models. One presented to the user form and the other being the pristine
|
||||
copy master.</li>
|
||||
</ul></div>
|
73
lib/angular/docs/partials/cookbook/buzz.html
Normal file
73
lib/angular/docs/partials/cookbook/buzz.html
Normal file
|
@ -0,0 +1,73 @@
|
|||
<h1><code ng:non-bindable=""></code>
|
||||
<span class="hint"></span>
|
||||
</h1>
|
||||
<div><p>External resources are URLs that provide JSON data, which are then rendered with the help of
|
||||
templates. Angular has a resource factory that can be used to give names to the URLs and then
|
||||
attach behavior to them. For example you can use the
|
||||
<a href="http://code.google.com/apis/buzz/v1/getting_started.html#background-operations|">Google Buzz API</a>
|
||||
to retrieve Buzz activity and comments.</p>
|
||||
|
||||
<h3>Source</h3>
|
||||
<div source-edit="" source-edit-deps="angular.js script.js" source-edit-html="index.html-1" source-edit-css="" source-edit-js="script.js-0" source-edit-unit="" source-edit-scenario="scenario.js-2"></div>
|
||||
<div class="tabbable"><div class="tab-pane" title="index.html">
|
||||
<pre class="prettyprint linenums" ng-set-text="index.html-1" ng-html-wrap=" angular.js script.js"></pre>
|
||||
<script type="text/ng-template" id="index.html-1">
|
||||
|
||||
<div ng-controller="BuzzController">
|
||||
<input ng-model="userId"/>
|
||||
<button ng-click="fetch()">fetch</button>
|
||||
<hr/>
|
||||
<div class="buzz" ng-repeat="item in activities.data.items">
|
||||
<h1 style="font-size: 15px;">
|
||||
<img ng-src="{{item.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/>
|
||||
<a ng-href="{{item.actor.profileUrl}}">{{item.actor.name}}</a>
|
||||
<a href ng-click="expandReplies(item)" style="float: right;">
|
||||
Expand replies: {{item.links.replies[0].count}}
|
||||
</a>
|
||||
</h2>
|
||||
{{item.object.content | html}}
|
||||
<div class="reply" ng-repeat="reply in item.replies.data.items" style="margin-left: 20px;">
|
||||
<img ng-src="{{reply.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/>
|
||||
<a ng-href="{{reply.actor.profileUrl}}">{{reply.actor.name}}</a>:
|
||||
{{reply.content | html}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="script.js">
|
||||
<pre class="prettyprint linenums" ng-set-text="script.js-0"></pre>
|
||||
<script type="text/ng-template" id="script.js-0">
|
||||
BuzzController.$inject = ['$scope', '$resource'];
|
||||
function BuzzController($scope, $resource) {
|
||||
$scope.userId = 'googlebuzz';
|
||||
$scope.Activity = $resource(
|
||||
'https://www.googleapis.com/buzz/v1/activities/:userId/:visibility/:activityId/:comments',
|
||||
{alt: 'json', callback: 'JSON_CALLBACK'},
|
||||
{ get: {method: 'JSONP', params: {visibility: '@self'}},
|
||||
replies: {method: 'JSONP', params: {visibility: '@self', comments: '@comments'}}
|
||||
});
|
||||
|
||||
$scope.fetch = function() {
|
||||
$scope.activities = $scope.Activity.get({userId:this.userId});
|
||||
}
|
||||
|
||||
$scope.expandReplies = function(activity) {
|
||||
activity.replies = $scope.Activity.replies({userId: this.userId, activityId: activity.id});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="End to end test">
|
||||
<pre class="prettyprint linenums" ng-set-text="scenario.js-2"></pre>
|
||||
<script type="text/ng-template" id="scenario.js-2">
|
||||
xit('fetch buzz and expand', function() {
|
||||
element(':button:contains(fetch)').click();
|
||||
expect(repeater('div.buzz').count()).toBeGreaterThan(0);
|
||||
element('.buzz a:contains(Expand replies):first').click();
|
||||
expect(repeater('div.reply').count()).toBeGreaterThan(0);
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div><h3>Demo</h3>
|
||||
<div class="well doc-example-live" ng-embed-app="" ng-set-html="index.html-1" ng-eval-javascript="script.js-0"></div></div>
|
172
lib/angular/docs/partials/cookbook/deeplinking.html
Normal file
172
lib/angular/docs/partials/cookbook/deeplinking.html
Normal file
|
@ -0,0 +1,172 @@
|
|||
<h1><code ng:non-bindable=""></code>
|
||||
<span class="hint"></span>
|
||||
</h1>
|
||||
<div><p>Deep linking allows you to encode the state of the application in the URL so that it can be
|
||||
bookmarked and the application can be restored from the URL to the same state.</p>
|
||||
|
||||
<p>While Angular does not force you to deal with bookmarks in any particular way, it has services
|
||||
which make the common case described here very easy to implement.</p>
|
||||
|
||||
<h2>Assumptions</h2>
|
||||
|
||||
<p>Your application consists of a single HTML page which bootstraps the application. We will refer
|
||||
to this page as the chrome.
|
||||
Your application is divided into several screens (or views) which the user can visit. For example,
|
||||
the home screen, settings screen, details screen, etc. For each of these screens, we would like to
|
||||
assign a URL so that it can be bookmarked and later restored. Each of these screens will be
|
||||
associated with a controller which define the screen's behavior. The most common case is that the
|
||||
screen will be constructed from an HTML snippet, which we will refer to as the partial. Screens can
|
||||
have multiple partials, but a single partial is the most common construct. This example makes the
|
||||
partial boundary visible using a blue line.</p>
|
||||
|
||||
<p>You can make a routing table which shows which URL maps to which partial view template and which
|
||||
controller.</p>
|
||||
|
||||
<h2>Example</h2>
|
||||
|
||||
<p>In this example we have a simple app which consist of two screens:</p>
|
||||
|
||||
<ul>
|
||||
<li>Welcome: url <code>welcome</code> Show the user contact information.</li>
|
||||
<li>Settings: url <code>settings</code> Show an edit screen for user contact information.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Source</h3>
|
||||
<div source-edit="deepLinking" source-edit-deps="angular.js angular-sanitize.js script.js" source-edit-html="index.html-4 settings.html welcome.html" source-edit-css="style.css" source-edit-js="script.js-3" source-edit-unit="" source-edit-scenario="scenario.js-5"></div>
|
||||
<div class="tabbable"><div class="tab-pane" title="index.html">
|
||||
<pre class="prettyprint linenums" ng-set-text="index.html-4" ng-html-wrap="deepLinking angular.js angular-sanitize.js script.js"></pre>
|
||||
<script type="text/ng-template" id="index.html-4">
|
||||
<div ng-controller="AppCntl">
|
||||
<h2>Your App Chrome</h2>
|
||||
[ <a href="welcome">Welcome</a> | <a href="settings">Settings</a> ]
|
||||
<hr/>
|
||||
<span class="partial-info">
|
||||
Partial: {{$route.current.template}}
|
||||
</span>
|
||||
<div ng-view></div>
|
||||
<small>Your app footer </small>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="settings.html">
|
||||
<pre class="prettyprint linenums" ng-set-text="settings.html"></pre>
|
||||
<script type="text/ng-template" id="settings.html">
|
||||
<label>Name:</label>
|
||||
<input type="text" ng:model="form.name" required>
|
||||
|
||||
<div ng:repeat="contact in form.contacts">
|
||||
<select ng:model="contact.type">
|
||||
<option>url</option>
|
||||
<option>email</option>
|
||||
<option>phone</option>
|
||||
</select>
|
||||
<input type="text" ng:model="contact.url">
|
||||
[ <a href="" ng:click="form.contacts.$remove(contact)">X</a> ]
|
||||
</div>
|
||||
<div>
|
||||
[ <a href="" ng:click="form.contacts.$add()">add</a> ]
|
||||
</div>
|
||||
|
||||
<button ng:click="cancel()">Cancel</button>
|
||||
<button ng:click="save()">Save</button>
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="welcome.html">
|
||||
<pre class="prettyprint linenums" ng-set-text="welcome.html"></pre>
|
||||
<script type="text/ng-template" id="welcome.html">
|
||||
Hello {{person.name}},
|
||||
<div>
|
||||
Your contact information:
|
||||
<div ng:repeat="contact in person.contacts">{{contact.type}}:
|
||||
<span ng-bind-html="contact.url|linky"></span>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="style.css">
|
||||
<pre class="prettyprint linenums" ng-set-text="style.css"></pre>
|
||||
<style type="text/css" id="style.css">
|
||||
[ng-view] {
|
||||
border: 1px solid blue;
|
||||
margin: 0;
|
||||
padding:1em;
|
||||
}
|
||||
|
||||
.partial-info {
|
||||
background-color: blue;
|
||||
color: white;
|
||||
padding: 3px;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
<div class="tab-pane" title="script.js">
|
||||
<pre class="prettyprint linenums" ng-set-text="script.js-3"></pre>
|
||||
<script type="text/ng-template" id="script.js-3">
|
||||
angular.module('deepLinking', ['ngSanitize'])
|
||||
.config(function($routeProvider) {
|
||||
$routeProvider.
|
||||
when("/welcome", {templateUrl:'welcome.html', controller:WelcomeCntl}).
|
||||
when("/settings", {templateUrl:'settings.html', controller:SettingsCntl});
|
||||
});
|
||||
|
||||
AppCntl.$inject = ['$scope', '$route']
|
||||
function AppCntl($scope, $route) {
|
||||
$scope.$route = $route;
|
||||
|
||||
// initialize the model to something useful
|
||||
$scope.person = {
|
||||
name:'anonymous',
|
||||
contacts:[{type:'email', url:'anonymous@example.com'}]
|
||||
};
|
||||
}
|
||||
|
||||
function WelcomeCntl($scope) {
|
||||
$scope.greet = function() {
|
||||
alert("Hello " + $scope.person.name);
|
||||
};
|
||||
}
|
||||
|
||||
function SettingsCntl($scope, $location) {
|
||||
$scope.cancel = function() {
|
||||
$scope.form = angular.copy($scope.person);
|
||||
};
|
||||
|
||||
$scope.save = function() {
|
||||
angular.copy($scope.form, $scope.person);
|
||||
$location.path('/welcome');
|
||||
};
|
||||
|
||||
$scope.cancel();
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="End to end test">
|
||||
<pre class="prettyprint linenums" ng-set-text="scenario.js-5"></pre>
|
||||
<script type="text/ng-template" id="scenario.js-5">
|
||||
it('should navigate to URL', function() {
|
||||
element('a:contains(Welcome)').click();
|
||||
expect(element('[ng-view]').text()).toMatch(/Hello anonymous/);
|
||||
element('a:contains(Settings)').click();
|
||||
input('form.name').enter('yourname');
|
||||
element(':button:contains(Save)').click();
|
||||
element('a:contains(Welcome)').click();
|
||||
expect(element('[ng-view]').text()).toMatch(/Hello yourname/);
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div><h3>Demo</h3>
|
||||
<div class="well doc-example-live" ng-embed-app="deepLinking" ng-set-html="index.html-4" ng-eval-javascript="script.js-3"></div>
|
||||
|
||||
<h2>Things to notice</h2>
|
||||
|
||||
<ul>
|
||||
<li>Routes are defined in the <code>AppCntl</code> class. The initialization of the controller causes the
|
||||
initialization of the <a href="api/ng.$route"><code>$route</code></a> service with the proper URL
|
||||
routes.</li>
|
||||
<li>The <a href="api/ng.$route"><code>$route</code></a> service then watches the URL and instantiates the
|
||||
appropriate controller when the URL changes.</li>
|
||||
<li>The <a href="api/ng.directive:ngView"><code>ngView</code></a> widget loads the
|
||||
view when the URL changes. It also sets the view scope to the newly instantiated controller.</li>
|
||||
<li>Changing the URL is sufficient to change the controller and view. It makes no difference whether
|
||||
the URL is changed programatically or by the user.</li>
|
||||
</ul></div>
|
125
lib/angular/docs/partials/cookbook/form.html
Normal file
125
lib/angular/docs/partials/cookbook/form.html
Normal file
|
@ -0,0 +1,125 @@
|
|||
<h1><code ng:non-bindable=""></code>
|
||||
<span class="hint"></span>
|
||||
</h1>
|
||||
<div><p>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.</p>
|
||||
|
||||
<h3>Source</h3>
|
||||
<div source-edit="" source-edit-deps="angular.js script.js" source-edit-html="index.html-7" source-edit-css="" source-edit-js="script.js-6" source-edit-unit="" source-edit-scenario="scenario.js-8"></div>
|
||||
<div class="tabbable"><div class="tab-pane" title="index.html">
|
||||
<pre class="prettyprint linenums" ng-set-text="index.html-7" ng-html-wrap=" angular.js script.js"></pre>
|
||||
<script type="text/ng-template" id="index.html-7">
|
||||
|
||||
<div ng-controller="FormController" class="example">
|
||||
|
||||
<label>Name:</label><br>
|
||||
<input type="text" ng-model="user.name" required/> <br><br>
|
||||
|
||||
<label>Address:</label><br>
|
||||
<input type="text" ng-model="user.address.line1" size="33" required> <br>
|
||||
<input type="text" ng-model="user.address.city" size="12" required>,
|
||||
<input type="text" ng-model="user.address.state"
|
||||
ng-pattern="state" size="2" required>
|
||||
<input type="text" ng-model="user.address.zip" size="5"
|
||||
ng-pattern="zip" required><br><br>
|
||||
|
||||
<label>Phone:</label>
|
||||
[ <a href="" ng-click="addContact()">add</a> ]
|
||||
<div ng-repeat="contact in user.contacts">
|
||||
<select ng-model="contact.type">
|
||||
<option>email</option>
|
||||
<option>phone</option>
|
||||
<option>pager</option>
|
||||
<option>IM</option>
|
||||
</select>
|
||||
<input type="text" ng-model="contact.value" required>
|
||||
[ <a href="" ng-click="removeContact(contact)">X</a> ]
|
||||
</div>
|
||||
<hr/>
|
||||
Debug View:
|
||||
<pre>user={{user | json}}</pre>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="script.js">
|
||||
<pre class="prettyprint linenums" ng-set-text="script.js-6"></pre>
|
||||
<script type="text/ng-template" id="script.js-6">
|
||||
function FormController($scope) {
|
||||
var user = $scope.user = {
|
||||
name: 'John Smith',
|
||||
address:{line1: '123 Main St.', city:'Anytown', state:'AA', zip:'12345'},
|
||||
contacts:[{type:'phone', value:'1(234) 555-1212'}]
|
||||
};
|
||||
$scope.state = /^\w\w$/;
|
||||
$scope.zip = /^\d\d\d\d\d$/;
|
||||
|
||||
$scope.addContact = function() {
|
||||
user.contacts.push({type:'email', value:''});
|
||||
};
|
||||
|
||||
$scope.removeContact = function(contact) {
|
||||
for (var i = 0, ii = user.contacts.length; i < ii; i++) {
|
||||
if (contact === user.contacts[i]) {
|
||||
$scope.user.contacts.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="End to end test">
|
||||
<pre class="prettyprint linenums" ng-set-text="scenario.js-8"></pre>
|
||||
<script type="text/ng-template" id="scenario.js-8">
|
||||
it('should show debug', function() {
|
||||
expect(binding('user')).toMatch(/John Smith/);
|
||||
});
|
||||
it('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/);
|
||||
});
|
||||
|
||||
it('should remove contact', function() {
|
||||
using('.example').element('a:contains(X)').click();
|
||||
expect(binding('user')).not().toMatch(/\(234\) 555\-1212/);
|
||||
});
|
||||
|
||||
it('should validate zip', function() {
|
||||
expect(using('.example').
|
||||
element(':input[ng\\:model="user.address.zip"]').
|
||||
prop('className')).not().toMatch(/ng-invalid/);
|
||||
using('.example').input('user.address.zip').enter('abc');
|
||||
expect(using('.example').
|
||||
element(':input[ng\\:model="user.address.zip"]').
|
||||
prop('className')).toMatch(/ng-invalid/);
|
||||
});
|
||||
|
||||
it('should validate state', function() {
|
||||
expect(using('.example').element(':input[ng\\:model="user.address.state"]').prop('className'))
|
||||
.not().toMatch(/ng-invalid/);
|
||||
using('.example').input('user.address.state').enter('XXX');
|
||||
expect(using('.example').element(':input[ng\\:model="user.address.state"]').prop('className'))
|
||||
.toMatch(/ng-invalid/);
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div><h3>Demo</h3>
|
||||
<div class="well doc-example-live" ng-embed-app="" ng-set-html="index.html-7" ng-eval-javascript="script.js-6"></div>
|
||||
|
||||
<h2>Things to notice</h2>
|
||||
|
||||
<ul>
|
||||
<li>The user data model is initialized <a href="api/ng.directive:ngController"><code>controller</code></a> and is
|
||||
available in the <a href="api/ng.$rootScope.Scope"><code>scope</code></a> with the initial data.</li>
|
||||
<li>For debugging purposes we have included a debug view of the model to better understand what
|
||||
is going on.</li>
|
||||
<li>The <a href="api/ng.directive:input"><code>input directives</code></a> simply refer
|
||||
to the model and are data-bound.</li>
|
||||
<li>The inputs validate. (Try leaving them blank or entering non digits in the zip field)</li>
|
||||
<li>In your application you can simply read from or write to the model and the form will be updated.</li>
|
||||
<li>By clicking the 'add' link you are adding new items into the <code>user.contacts</code> array which are then
|
||||
reflected in the view.</li>
|
||||
</ul></div>
|
52
lib/angular/docs/partials/cookbook/helloworld.html
Normal file
52
lib/angular/docs/partials/cookbook/helloworld.html
Normal file
|
@ -0,0 +1,52 @@
|
|||
<h1><code ng:non-bindable=""></code>
|
||||
<span class="hint"></span>
|
||||
</h1>
|
||||
<div><h3>Source</h3>
|
||||
<div source-edit="" source-edit-deps="angular.js script.js" source-edit-html="index.html-10" source-edit-css="" source-edit-js="script.js-9" source-edit-unit="" source-edit-scenario="scenario.js-11"></div>
|
||||
<div class="tabbable"><div class="tab-pane" title="index.html">
|
||||
<pre class="prettyprint linenums" ng-set-text="index.html-10" ng-html-wrap=" angular.js script.js"></pre>
|
||||
<script type="text/ng-template" id="index.html-10">
|
||||
|
||||
<div ng-controller="HelloCntl">
|
||||
Your name: <input type="text" ng-model="name" value="World"/>
|
||||
<hr/>
|
||||
Hello {{name}}!
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="script.js">
|
||||
<pre class="prettyprint linenums" ng-set-text="script.js-9"></pre>
|
||||
<script type="text/ng-template" id="script.js-9">
|
||||
function HelloCntl($scope) {
|
||||
$scope.name = 'World';
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="End to end test">
|
||||
<pre class="prettyprint linenums" ng-set-text="scenario.js-11"></pre>
|
||||
<script type="text/ng-template" id="scenario.js-11">
|
||||
it('should change the binding when user enters text', function() {
|
||||
expect(binding('name')).toEqual('World');
|
||||
input('name').enter('angular');
|
||||
expect(binding('name')).toEqual('angular');
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div><h3>Demo</h3>
|
||||
<div class="well doc-example-live" ng-embed-app="" ng-set-html="index.html-10" ng-eval-javascript="script.js-9"></div>
|
||||
|
||||
<h2>Things to notice</h2>
|
||||
|
||||
<p>Take a look through the source and note:</p>
|
||||
|
||||
<ul>
|
||||
<li>The script tag that <a href="guide/bootstrap">bootstraps</a> the Angular environment.</li>
|
||||
<li>The text <a href="api/ng.directive:input"><code>input form control</code></a> which is
|
||||
bound to the greeting name text.</li>
|
||||
<li>There is no need for listener registration and event firing on change events.</li>
|
||||
<li>The implicit presence of the <code>name</code> variable which is in the root <a href="api/ng.$rootScope.Scope"><code>scope</code></a>.</li>
|
||||
<li>The double curly brace <code>{{markup}}</code>, which binds the name variable to the greeting text.</li>
|
||||
<li>The concept of <a href="guide/dev_guide.templates.databinding">data binding</a>, which reflects any
|
||||
changes to the
|
||||
input field in the greeting text.</li>
|
||||
</ul></div>
|
50
lib/angular/docs/partials/cookbook/index.html
Normal file
50
lib/angular/docs/partials/cookbook/index.html
Normal file
|
@ -0,0 +1,50 @@
|
|||
<h1><code ng:non-bindable=""></code>
|
||||
<span class="hint"></span>
|
||||
</h1>
|
||||
<div><p>Welcome to the Angular cookbook. Here we will show you typical uses of Angular by example.</p>
|
||||
|
||||
<h2>Hello World</h2>
|
||||
|
||||
<p><a href="cookbook/helloworld">Hello World</a>: The simplest possible application that demonstrates the
|
||||
classic Hello World!</p>
|
||||
|
||||
<h2>Basic Form</h2>
|
||||
|
||||
<p><a href="cookbook/form">Basic Form</a>: Displaying forms to the user for editing is the bread and butter
|
||||
of web applications. Angular makes forms easy through bidirectional data binding.</p>
|
||||
|
||||
<h2>Advanced Form</h2>
|
||||
|
||||
<p><a href="cookbook/advancedform">Advanced Form</a>: 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.</p>
|
||||
|
||||
<h2>Model View Controller</h2>
|
||||
|
||||
<p><a href="cookbook/mvc">MVC</a>: 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.</p>
|
||||
|
||||
<h2>Multi-page App and Deep Linking</h2>
|
||||
|
||||
<p><a href="cookbook/deeplinking">Deep Linking</a>: 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.</p>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<h2>Services</h2>
|
||||
|
||||
<p><a href="api/ng">Services</a>: 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).</p>
|
||||
|
||||
<h2>External Resources</h2>
|
||||
|
||||
<p><a href="cookbook/buzz">Resources</a>: 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.</p></div>
|
138
lib/angular/docs/partials/cookbook/mvc.html
Normal file
138
lib/angular/docs/partials/cookbook/mvc.html
Normal file
|
@ -0,0 +1,138 @@
|
|||
<h1><code ng:non-bindable=""></code>
|
||||
<span class="hint"></span>
|
||||
</h1>
|
||||
<div><p>MVC allows for a clean and testable separation between the behavior (controller) and the view
|
||||
(HTML template). A Controller is just a JavaScript class which is grafted onto the scope of the
|
||||
view. This makes it very easy for the controller and the view to share the model.</p>
|
||||
|
||||
<p>The model is a set of objects and primitives that are referenced from the Scope ($scope) object.
|
||||
This makes it very easy to test the controller in isolation since one can simply instantiate the
|
||||
controller and test without a view, because there is no connection between the controller and the
|
||||
view.</p>
|
||||
|
||||
<h3>Source</h3>
|
||||
<div source-edit="" source-edit-deps="angular.js script.js" source-edit-html="index.html-13" source-edit-css="" source-edit-js="script.js-12" source-edit-unit="" source-edit-scenario="scenario.js-14"></div>
|
||||
<div class="tabbable"><div class="tab-pane" title="index.html">
|
||||
<pre class="prettyprint linenums" ng-set-text="index.html-13" ng-html-wrap=" angular.js script.js"></pre>
|
||||
<script type="text/ng-template" id="index.html-13">
|
||||
|
||||
|
||||
<h4>Tic-Tac-Toe</h4>
|
||||
<div ng-controller="TicTacToeCntl">
|
||||
Next Player: {{nextMove}}
|
||||
<div class="winner" ng-show="winner">Player {{winner}} has won!</div>
|
||||
<table class="board">
|
||||
<tr ng-repeat="row in board" style="height:15px;">
|
||||
<td ng-repeat="cell in row" ng-style="cellStyle"
|
||||
ng-click="dropPiece($parent.$index, $index)">{{cell}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button ng-click="reset()">reset board</button>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="script.js">
|
||||
<pre class="prettyprint linenums" ng-set-text="script.js-12"></pre>
|
||||
<script type="text/ng-template" id="script.js-12">
|
||||
function TicTacToeCntl($scope, $location) {
|
||||
$scope.cellStyle= {
|
||||
'height': '20px',
|
||||
'width': '20px',
|
||||
'border': '1px solid black',
|
||||
'text-align': 'center',
|
||||
'vertical-align': 'middle',
|
||||
'cursor': 'pointer'
|
||||
};
|
||||
|
||||
$scope.reset = function() {
|
||||
$scope.board = [
|
||||
['', '', ''],
|
||||
['', '', ''],
|
||||
['', '', '']
|
||||
];
|
||||
$scope.nextMove = 'X';
|
||||
$scope.winner = '';
|
||||
setUrl();
|
||||
};
|
||||
|
||||
$scope.dropPiece = function(row, col) {
|
||||
if (!$scope.winner && !$scope.board[row][col]) {
|
||||
$scope.board[row][col] = $scope.nextMove;
|
||||
$scope.nextMove = $scope.nextMove == 'X' ? 'O' : 'X';
|
||||
setUrl();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.reset();
|
||||
$scope.$watch(function() { return $location.search().board;}, readUrl);
|
||||
|
||||
function setUrl() {
|
||||
var rows = [];
|
||||
angular.forEach($scope.board, function(row) {
|
||||
rows.push(row.join(','));
|
||||
});
|
||||
$location.search({board: rows.join(';') + '/' + $scope.nextMove});
|
||||
}
|
||||
|
||||
function grade() {
|
||||
var b = $scope.board;
|
||||
$scope.winner =
|
||||
row(0) || row(1) || row(2) ||
|
||||
col(0) || col(1) || col(2) ||
|
||||
diagonal(-1) || diagonal(1);
|
||||
function row(row) { return same(b[row][0], b[row][1], b[row][2]);}
|
||||
function col(col) { return same(b[0][col], b[1][col], b[2][col]);}
|
||||
function diagonal(i) { return same(b[0][1-i], b[1][1], b[2][1+i]);}
|
||||
function same(a, b, c) { return (a==b && b==c) ? a : '';};
|
||||
}
|
||||
|
||||
function readUrl(value) {
|
||||
if (value) {
|
||||
value = value.split('/');
|
||||
$scope.nextMove = value[1];
|
||||
angular.forEach(value[0].split(';'), function(row, col){
|
||||
$scope.board[col] = row.split(',');
|
||||
});
|
||||
grade();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div class="tab-pane" title="End to end test">
|
||||
<pre class="prettyprint linenums" ng-set-text="scenario.js-14"></pre>
|
||||
<script type="text/ng-template" id="scenario.js-14">
|
||||
it('should play a game', function() {
|
||||
piece(1, 1);
|
||||
expect(binding('nextMove')).toEqual('O');
|
||||
piece(3, 1);
|
||||
expect(binding('nextMove')).toEqual('X');
|
||||
piece(1, 2);
|
||||
piece(3, 2);
|
||||
piece(1, 3);
|
||||
expect(element('.winner').text()).toEqual('Player X has won!');
|
||||
});
|
||||
|
||||
function piece(row, col) {
|
||||
element('.board tr:nth-child('+row+') td:nth-child('+col+')').click();
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
</div><h3>Demo</h3>
|
||||
<div class="well doc-example-live" ng-embed-app="" ng-set-html="index.html-13" ng-eval-javascript="script.js-12"></div>
|
||||
|
||||
<h2>Things to notice</h2>
|
||||
|
||||
<ul>
|
||||
<li>The controller is defined in JavaScript and has no reference to the rendering logic.</li>
|
||||
<li>The controller is instantiated by Angular and injected into the view.</li>
|
||||
<li>The controller can be instantiated in isolation (without a view) and the code will still execute.
|
||||
This makes it very testable.</li>
|
||||
<li>The HTML view is a projection of the model. In the above example, the model is stored in the
|
||||
board variable.</li>
|
||||
<li>All of the controller's properties (such as board and nextMove) are available to the view.</li>
|
||||
<li>Changing the model changes the view.</li>
|
||||
<li>The view can call any controller function.</li>
|
||||
<li>In this example, the <code>setUrl()</code> and <code>readUrl()</code> functions copy the game state to/from the URL's
|
||||
hash so the browser's back button will undo game steps. See deep-linking. This example calls <a href="api/ng.$rootScope.Scope#$watch"><code>$watch()</code></a> to set up a listener that invokes <code>readUrl()</code> when needed.</li>
|
||||
</ul></div>
|
Loading…
Add table
Add a link
Reference in a new issue