mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-06-13 00:28:10 +08:00
docs(bike-shed-migration): convert guide <doc:...> examples to <example>...
This CL also contains style fixes as the converted scripts caused jshint to complain.
This commit is contained in:
committed by
Peter Bacon Darwin
parent
896e34689d
commit
f7fad29fd9
@@ -387,120 +387,116 @@ redirect to regular / hashbang url, as this conversion happens only during parsi
|
||||
= on page reload.
|
||||
|
||||
In this examples we use `<base href="/base/index.html" />`
|
||||
<doc:example>
|
||||
<doc:source source="false">
|
||||
<example>
|
||||
<file name="index.html">
|
||||
<div id="html5-mode" ng-controller="Html5Cntl">
|
||||
<h3>Browser with History API</h3>
|
||||
<div ng-address-bar browser="html5"></div><br><br>
|
||||
$location.protocol() = {{$location.protocol()}}<br>
|
||||
$location.host() = {{$location.host()}}<br>
|
||||
$location.port() = {{$location.port()}}<br>
|
||||
$location.path() = {{$location.path()}}<br>
|
||||
$location.search() = {{$location.search()}}<br>
|
||||
$location.hash() = {{$location.hash()}}<br>
|
||||
<a href="http://www.example.com/base/first?a=b">/base/first?a=b</a> |
|
||||
<a href="http://www.example.com/base/sec/ond?flag#hash">sec/ond?flag#hash</a> |
|
||||
<a href="/other-base/another?search">external</a>
|
||||
</div>
|
||||
|
||||
<div ng-non-bindable class="html5-hashbang-example">
|
||||
<div id="html5-mode" ng-controller="Html5Cntl">
|
||||
<h3>Browser with History API</h3>
|
||||
<div ng-address-bar browser="html5"></div><br><br>
|
||||
$location.protocol() = {{$location.protocol()}}<br>
|
||||
$location.host() = {{$location.host()}}<br>
|
||||
$location.port() = {{$location.port()}}<br>
|
||||
$location.path() = {{$location.path()}}<br>
|
||||
$location.search() = {{$location.search()}}<br>
|
||||
$location.hash() = {{$location.hash()}}<br>
|
||||
<a href="http://www.example.com/base/first?a=b">/base/first?a=b</a> |
|
||||
<a href="http://www.example.com/base/sec/ond?flag#hash">sec/ond?flag#hash</a> |
|
||||
<a href="/other-base/another?search">external</a>
|
||||
</div>
|
||||
<div id="hashbang-mode" ng-controller="HashbangCntl">
|
||||
<h3>Browser without History API</h3>
|
||||
<div ng-address-bar browser="hashbang"></div><br><br>
|
||||
$location.protocol() = {{$location.protocol()}}<br>
|
||||
$location.host() = {{$location.host()}}<br>
|
||||
$location.port() = {{$location.port()}}<br>
|
||||
$location.path() = {{$location.path()}}<br>
|
||||
$location.search() = {{$location.search()}}<br>
|
||||
$location.hash() = {{$location.hash()}}<br>
|
||||
<a href="http://www.example.com/base/first?a=b">/base/first?a=b</a> |
|
||||
<a href="http://www.example.com/base/sec/ond?flag#hash">sec/ond?flag#hash</a> |
|
||||
<a href="/other-base/another?search">external</a>
|
||||
</div>
|
||||
</file>
|
||||
|
||||
<div id="hashbang-mode" ng-controller="HashbangCntl">
|
||||
<h3>Browser without History API</h3>
|
||||
<div ng-address-bar browser="hashbang"></div><br><br>
|
||||
$location.protocol() = {{$location.protocol()}}<br>
|
||||
$location.host() = {{$location.host()}}<br>
|
||||
$location.port() = {{$location.port()}}<br>
|
||||
$location.path() = {{$location.path()}}<br>
|
||||
$location.search() = {{$location.search()}}<br>
|
||||
$location.hash() = {{$location.hash()}}<br>
|
||||
<a href="http://www.example.com/base/first?a=b">/base/first?a=b</a> |
|
||||
<a href="http://www.example.com/base/sec/ond?flag#hash">sec/ond?flag#hash</a> |
|
||||
<a href="/other-base/another?search">external</a>
|
||||
</div>
|
||||
</div>
|
||||
<file name="script.js">
|
||||
function FakeBrowser(initUrl, baseHref) {
|
||||
this.onUrlChange = function(fn) {
|
||||
this.urlChange = fn;
|
||||
};
|
||||
|
||||
<script>
|
||||
function FakeBrowser(initUrl, baseHref) {
|
||||
this.onUrlChange = function(fn) {
|
||||
this.urlChange = fn;
|
||||
this.url = function() {
|
||||
return initUrl;
|
||||
};
|
||||
|
||||
this.defer = function(fn, delay) {
|
||||
setTimeout(function() { fn(); }, delay || 0);
|
||||
};
|
||||
|
||||
this.baseHref = function() {
|
||||
return baseHref;
|
||||
};
|
||||
|
||||
this.notifyWhenOutstandingRequests = angular.noop;
|
||||
}
|
||||
|
||||
var browsers = {
|
||||
html5: new FakeBrowser('http://www.example.com/base/path?a=b#h', '/base/index.html'),
|
||||
hashbang: new FakeBrowser('http://www.example.com/base/index.html#!/path?a=b#h', '/base/index.html')
|
||||
};
|
||||
|
||||
this.url = function() {
|
||||
return initUrl;
|
||||
};
|
||||
function Html5Cntl($scope, $location) {
|
||||
$scope.$location = $location;
|
||||
}
|
||||
|
||||
this.defer = function(fn, delay) {
|
||||
setTimeout(function() { fn(); }, delay || 0);
|
||||
};
|
||||
function HashbangCntl($scope, $location) {
|
||||
$scope.$location = $location;
|
||||
}
|
||||
|
||||
this.baseHref = function() {
|
||||
return baseHref;
|
||||
};
|
||||
function initEnv(name) {
|
||||
var root = angular.element(document.getElementById(name + '-mode'));
|
||||
// We must kill a link to the injector for this element otherwise angular will
|
||||
// complain that it has been bootstrapped already.
|
||||
root.data('$injector', null);
|
||||
angular.bootstrap(root, [function($compileProvider, $locationProvider, $provide){
|
||||
$locationProvider.html5Mode(true).hashPrefix('!');
|
||||
|
||||
this.notifyWhenOutstandingRequests = angular.noop;
|
||||
}
|
||||
$provide.value('$browser', browsers[name]);
|
||||
$provide.value('$sniffer', {history: name == 'html5'});
|
||||
|
||||
var browsers = {
|
||||
html5: new FakeBrowser('http://www.example.com/base/path?a=b#h', '/base/index.html'),
|
||||
hashbang: new FakeBrowser('http://www.example.com/base/index.html#!/path?a=b#h', '/base/index.html')
|
||||
};
|
||||
$compileProvider.directive('ngAddressBar', function() {
|
||||
return function(scope, elm, attrs) {
|
||||
var browser = browsers[attrs.browser],
|
||||
input = angular.element('<input type="text" style="width: 400px">').val(browser.url()),
|
||||
delay;
|
||||
|
||||
function Html5Cntl($scope, $location) {
|
||||
$scope.$location = $location;
|
||||
}
|
||||
input.on('keypress keyup keydown', function() {
|
||||
if (!delay) {
|
||||
delay = setTimeout(fireUrlChange, 250);
|
||||
}
|
||||
});
|
||||
|
||||
function HashbangCntl($scope, $location) {
|
||||
$scope.$location = $location;
|
||||
}
|
||||
browser.url = function(url) {
|
||||
return input.val(url);
|
||||
};
|
||||
|
||||
function initEnv(name) {
|
||||
var root = angular.element(document.getElementById(name + '-mode'));
|
||||
// We must kill a link to the injector for this element otherwise angular will
|
||||
// complain that it has been bootstrapped already.
|
||||
root.data('$injector', null);
|
||||
angular.bootstrap(root, [function($compileProvider, $locationProvider, $provide){
|
||||
$locationProvider.html5Mode(true).hashPrefix('!');
|
||||
elm.append('Address: ').append(input);
|
||||
|
||||
$provide.value('$browser', browsers[name]);
|
||||
$provide.value('$sniffer', {history: name == 'html5'});
|
||||
|
||||
$compileProvider.directive('ngAddressBar', function() {
|
||||
return function(scope, elm, attrs) {
|
||||
var browser = browsers[attrs.browser],
|
||||
input = angular.element('<input type="text" style="width: 400px">').val(browser.url()),
|
||||
delay;
|
||||
|
||||
input.on('keypress keyup keydown', function() {
|
||||
if (!delay) {
|
||||
delay = setTimeout(fireUrlChange, 250);
|
||||
function fireUrlChange() {
|
||||
delay = null;
|
||||
browser.urlChange(input.val());
|
||||
}
|
||||
});
|
||||
|
||||
browser.url = function(url) {
|
||||
return input.val(url);
|
||||
};
|
||||
|
||||
elm.append('Address: ').append(input);
|
||||
|
||||
function fireUrlChange() {
|
||||
delay = null;
|
||||
browser.urlChange(input.val());
|
||||
}
|
||||
};
|
||||
});
|
||||
}]);
|
||||
root.on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
}]);
|
||||
root.on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
initEnv('html5');
|
||||
initEnv('hashbang');
|
||||
</script>
|
||||
|
||||
</doc:source>
|
||||
</doc:example>
|
||||
initEnv('html5');
|
||||
initEnv('hashbang');
|
||||
</file>
|
||||
</example>
|
||||
|
||||
|
||||
# Caveats
|
||||
|
||||
@@ -28,45 +28,46 @@ function myController($loc, $log) {
|
||||
myController.$inject = ['$location', '$log'];
|
||||
```
|
||||
|
||||
<doc:example module="MyServiceModule">
|
||||
<doc:source>
|
||||
<script>
|
||||
angular.
|
||||
module('MyServiceModule', []).
|
||||
factory('notify', ['$window', function(win) {
|
||||
var msgs = [];
|
||||
return function(msg) {
|
||||
msgs.push(msg);
|
||||
if (msgs.length == 3) {
|
||||
win.alert(msgs.join("\n"));
|
||||
msgs = [];
|
||||
}
|
||||
};
|
||||
}]);
|
||||
<example module="MyServiceModule">
|
||||
<file name="index.html">
|
||||
<div id="simple" ng-controller="myController">
|
||||
<p>Let's try this simple notify service, injected into the controller...</p>
|
||||
<input ng-init="message='test'" ng-model="message" >
|
||||
<button ng-click="callNotify(message);">NOTIFY</button>
|
||||
<p>(you have to click 3 times to see an alert)</p>
|
||||
</div>
|
||||
</file>
|
||||
|
||||
function myController(scope, notifyService) {
|
||||
scope.callNotify = function(msg) {
|
||||
notifyService(msg);
|
||||
};
|
||||
}
|
||||
<file name="script.js">
|
||||
angular.
|
||||
module('MyServiceModule', []).
|
||||
factory('notify', ['$window', function(win) {
|
||||
var msgs = [];
|
||||
return function(msg) {
|
||||
msgs.push(msg);
|
||||
if (msgs.length == 3) {
|
||||
win.alert(msgs.join("\n"));
|
||||
msgs = [];
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
myController.$inject = ['$scope','notify'];
|
||||
</script>
|
||||
function myController(scope, notifyService) {
|
||||
scope.callNotify = function(msg) {
|
||||
notifyService(msg);
|
||||
};
|
||||
}
|
||||
|
||||
<div id="simple" ng-controller="myController">
|
||||
<p>Let's try this simple notify service, injected into the controller...</p>
|
||||
<input ng-init="message='test'" ng-model="message" >
|
||||
<button ng-click="callNotify(message);">NOTIFY</button>
|
||||
<p>(you have to click 3 times to see an alert)</p>
|
||||
</div>
|
||||
</doc:source>
|
||||
<doc:protractor>
|
||||
it('should test service', function() {
|
||||
expect(element(by.id('simple')).element(by.model('message')).getAttribute('value'))
|
||||
.toEqual('test');
|
||||
});
|
||||
</doc:protractor>
|
||||
</doc:example>
|
||||
myController.$inject = ['$scope','notify'];
|
||||
</file>
|
||||
|
||||
<file name="protractor.js" type="protractor">
|
||||
it('should test service', function() {
|
||||
expect(element(by.id('simple')).element(by.model('message')).getAttribute('value'))
|
||||
.toEqual('test');
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
|
||||
## Implicit Dependency Injection
|
||||
|
||||
@@ -74,36 +75,37 @@ A new feature of Angular DI allows it to determine the dependency from the name
|
||||
Let's rewrite the above example to show the use of this implicit dependency injection of
|
||||
`$window`, `$scope`, and our `notify` service:
|
||||
|
||||
<doc:example module="MyServiceModuleDI">
|
||||
<doc:source>
|
||||
<script>
|
||||
angular.
|
||||
module('MyServiceModuleDI', []).
|
||||
factory('notify', function($window) {
|
||||
var msgs = [];
|
||||
return function(msg) {
|
||||
msgs.push(msg);
|
||||
if (msgs.length == 3) {
|
||||
$window.alert(msgs.join("\n"));
|
||||
msgs = [];
|
||||
}
|
||||
};
|
||||
});
|
||||
<example module="MyServiceModuleDI">
|
||||
<file name="index.html">
|
||||
<div id="implicit" ng-controller="myController">
|
||||
<p>Let's try the notify service, that is implicitly injected into the controller...</p>
|
||||
<input ng-init="message='test'" ng-model="message">
|
||||
<button ng-click="callNotify(message);">NOTIFY</button>
|
||||
<p>(you have to click 3 times to see an alert)</p>
|
||||
</div>
|
||||
</file>
|
||||
|
||||
function myController($scope, notify) {
|
||||
$scope.callNotify = function(msg) {
|
||||
notify(msg);
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<div id="implicit" ng-controller="myController">
|
||||
<p>Let's try the notify service, that is implicitly injected into the controller...</p>
|
||||
<input ng-init="message='test'" ng-model="message">
|
||||
<button ng-click="callNotify(message);">NOTIFY</button>
|
||||
<p>(you have to click 3 times to see an alert)</p>
|
||||
</div>
|
||||
</doc:source>
|
||||
</doc:example>
|
||||
<file name="script.js">
|
||||
angular.
|
||||
module('MyServiceModuleDI', []).
|
||||
factory('notify', function($window) {
|
||||
var msgs = [];
|
||||
return function(msg) {
|
||||
msgs.push(msg);
|
||||
if (msgs.length == 3) {
|
||||
$window.alert(msgs.join("\n"));
|
||||
msgs = [];
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
function myController($scope, notify) {
|
||||
$scope.callNotify = function(msg) {
|
||||
notify(msg);
|
||||
};
|
||||
}
|
||||
</file>
|
||||
</example>
|
||||
|
||||
However, if you plan to [minify](http://en.wikipedia.org/wiki/Minification_(programming)) your
|
||||
code, your variable names will get renamed in which case you will still need to explicitly specify
|
||||
|
||||
@@ -33,55 +33,58 @@ controller method and call the method. If you want to `eval()` an angular expres
|
||||
JavaScript, use the {@link ng.$rootScope.Scope#methods_$eval `$eval()`} method.
|
||||
|
||||
## Example
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
1+2={{1+2}}
|
||||
</doc:source>
|
||||
<doc:protractor>
|
||||
it('should calculate expression in binding', function() {
|
||||
expect(element(by.binding('1+2')).getText()).toEqual('1+2=3');
|
||||
});
|
||||
</doc:protractor>
|
||||
</doc:example>
|
||||
<example>
|
||||
<file name="index.html">
|
||||
1+2={{1+2}}
|
||||
</file>
|
||||
|
||||
<file name="protractor.js" type="protractor">
|
||||
it('should calculate expression in binding', function() {
|
||||
expect(element(by.binding('1+2')).getText()).toEqual('1+2=3');
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
|
||||
You can try evaluating different expressions here:
|
||||
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
<script>
|
||||
function Cntl2($scope) {
|
||||
var exprs = $scope.exprs = [];
|
||||
$scope.expr = '3*10|currency';
|
||||
$scope.addExp = function(expr) {
|
||||
exprs.push(expr);
|
||||
};
|
||||
<example>
|
||||
<file name="index.html">
|
||||
<div ng-controller="Cntl2" class="expressions">
|
||||
Expression:
|
||||
<input type='text' ng-model="expr" size="80"/>
|
||||
<button ng-click="addExp(expr)">Evaluate</button>
|
||||
<ul>
|
||||
<li ng-repeat="expr in exprs track by $index">
|
||||
[ <a href="" ng-click="removeExp($index)">X</a> ]
|
||||
<tt>{{expr}}</tt> => <span ng-bind="$parent.$eval(expr)"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</file>
|
||||
|
||||
$scope.removeExp = function(index) {
|
||||
exprs.splice(index, 1);
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<div ng-controller="Cntl2" class="expressions">
|
||||
Expression:
|
||||
<input type='text' ng-model="expr" size="80"/>
|
||||
<button ng-click="addExp(expr)">Evaluate</button>
|
||||
<ul>
|
||||
<li ng-repeat="expr in exprs track by $index">
|
||||
[ <a href="" ng-click="removeExp($index)">X</a> ]
|
||||
<tt>{{expr}}</tt> => <span ng-bind="$parent.$eval(expr)"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</doc:source>
|
||||
<doc:protractor>
|
||||
it('should allow user expression testing', function() {
|
||||
element(by.css('.expressions button')).click();
|
||||
var lis = element(by.css('.expressions ul')).element.all(by.repeater('expr in exprs'));
|
||||
expect(lis.count()).toBe(1);
|
||||
expect(lis.get(0).getText()).toEqual('[ X ] 3*10|currency => $30.00');
|
||||
});
|
||||
</doc:protractor>
|
||||
</doc:example>
|
||||
<file name="script.js">
|
||||
function Cntl2($scope) {
|
||||
var exprs = $scope.exprs = [];
|
||||
$scope.expr = '3*10|currency';
|
||||
$scope.addExp = function(expr) {
|
||||
exprs.push(expr);
|
||||
};
|
||||
|
||||
$scope.removeExp = function(index) {
|
||||
exprs.splice(index, 1);
|
||||
};
|
||||
}
|
||||
</file>
|
||||
|
||||
<file name="protractor.js" type="protractor">
|
||||
it('should allow user expression testing', function() {
|
||||
element(by.css('.expressions button')).click();
|
||||
var lis = element(by.css('.expressions ul')).element.all(by.repeater('expr in exprs'));
|
||||
expect(lis.count()).toBe(1);
|
||||
expect(lis.get(0).getText()).toEqual('[ X ] 3*10|currency => $30.00');
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
|
||||
|
||||
# Property Evaluation
|
||||
@@ -92,38 +95,40 @@ to global window properties, Angular expressions have to use {@link ng.$window
|
||||
defined on `window`, in an expression you must use `$window.alert()`. This is done intentionally to
|
||||
prevent accidental access to the global state (a common source of subtle bugs).
|
||||
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
<script>
|
||||
function Cntl1($window, $scope){
|
||||
$scope.name = 'World';
|
||||
<example>
|
||||
<file name="index.html">
|
||||
<div class="example2" ng-controller="Cntl1">
|
||||
Name: <input ng-model="name" type="text"/>
|
||||
<button ng-click="greet()">Greet</button>
|
||||
</div>
|
||||
</file>
|
||||
|
||||
$scope.greet = function() {
|
||||
$window.alert('Hello ' + $scope.name);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<div class="example2" ng-controller="Cntl1">
|
||||
Name: <input ng-model="name" type="text"/>
|
||||
<button ng-click="greet()">Greet</button>
|
||||
</div>
|
||||
</doc:source>
|
||||
<doc:protractor>
|
||||
it('should calculate expression in binding', function() {
|
||||
if (browser.params.browser = 'safari') {
|
||||
// Safari can't handle dialogs.
|
||||
return;
|
||||
};
|
||||
element(by.css('[ng-click="greet()"]')).click();
|
||||
<file name="script.js">
|
||||
function Cntl1($window, $scope){
|
||||
$scope.name = 'World';
|
||||
|
||||
var alertDialog = browser.switchTo().alert();
|
||||
$scope.greet = function() {
|
||||
$window.alert('Hello ' + $scope.name);
|
||||
};
|
||||
}
|
||||
</file>
|
||||
|
||||
expect(alertDialog.getText()).toEqual('Hello World');
|
||||
<file name="protractor.js" type="protractor">
|
||||
it('should calculate expression in binding', function() {
|
||||
if (browser.params.browser == 'safari') {
|
||||
// Safari can't handle dialogs.
|
||||
return;
|
||||
}
|
||||
element(by.css('[ng-click="greet()"]')).click();
|
||||
|
||||
alertDialog.accept();
|
||||
});
|
||||
</doc:protractor>
|
||||
</doc:example>
|
||||
var alertDialog = browser.switchTo().alert();
|
||||
|
||||
expect(alertDialog.getText()).toEqual('Hello World');
|
||||
|
||||
alertDialog.accept();
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
|
||||
## Forgiving
|
||||
|
||||
|
||||
@@ -47,35 +47,35 @@ The example below therefore calls the filter directly in the controller.
|
||||
By this, the controller is able to call the filter only when needed (e.g. when the data is loaded from the backend
|
||||
or the filter expression is changed).
|
||||
|
||||
<doc:example module="FilterInControllerModule">
|
||||
<doc:source>
|
||||
<script>
|
||||
angular.module('FilterInControllerModule', []).
|
||||
controller('FilterController', ['filterFilter', function(filterFilter) {
|
||||
this.array = [
|
||||
{name: 'Tobias'},
|
||||
{name: 'Jeff'},
|
||||
{name: 'Brian'},
|
||||
{name: 'Igor'},
|
||||
{name: 'James'},
|
||||
{name: 'Brad'}
|
||||
];
|
||||
this.filteredArray = filterFilter(this.array, 'a');
|
||||
}]);
|
||||
</script>
|
||||
<example module="FilterInControllerModule">
|
||||
<file name="index.html">
|
||||
<div ng-controller="FilterController as ctrl">
|
||||
<div>
|
||||
All entries:
|
||||
<span ng-repeat="entry in ctrl.array">{{entry.name}} </span>
|
||||
</div>
|
||||
<div>
|
||||
Entries that contain an "a":
|
||||
<span ng-repeat="entry in ctrl.filteredArray">{{entry.name}} </span>
|
||||
</div>
|
||||
</div>
|
||||
</file>
|
||||
|
||||
<div ng-controller="FilterController as ctrl">
|
||||
<div>
|
||||
All entries:
|
||||
<span ng-repeat="entry in ctrl.array">{{entry.name}} </span>
|
||||
</div>
|
||||
<div>
|
||||
Entries that contain an "a":
|
||||
<span ng-repeat="entry in ctrl.filteredArray">{{entry.name}} </span>
|
||||
</div>
|
||||
</div>
|
||||
</doc:source>
|
||||
</doc:example>
|
||||
<file name="script.js">
|
||||
angular.module('FilterInControllerModule', []).
|
||||
controller('FilterController', ['filterFilter', function(filterFilter) {
|
||||
this.array = [
|
||||
{name: 'Tobias'},
|
||||
{name: 'Jeff'},
|
||||
{name: 'Brian'},
|
||||
{name: 'Igor'},
|
||||
{name: 'James'},
|
||||
{name: 'Brad'}
|
||||
];
|
||||
this.filteredArray = filterFilter(this.array, 'a');
|
||||
}]);
|
||||
</file>
|
||||
</example>
|
||||
|
||||
|
||||
## Creating custom filters
|
||||
@@ -89,37 +89,37 @@ function.
|
||||
The following sample filter reverses a text string. In addition, it conditionally makes the
|
||||
text upper-case.
|
||||
|
||||
<doc:example module="MyReverseModule">
|
||||
<doc:source>
|
||||
<script>
|
||||
angular.module('MyReverseModule', []).
|
||||
filter('reverse', function() {
|
||||
return function(input, uppercase) {
|
||||
var out = "";
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
out = input.charAt(i) + out;
|
||||
}
|
||||
// conditional based on optional argument
|
||||
if (uppercase) {
|
||||
out = out.toUpperCase();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
});
|
||||
<example module="MyReverseModule">
|
||||
<file name="index.html">
|
||||
<div ng-controller="Ctrl">
|
||||
<input ng-model="greeting" type="greeting"><br>
|
||||
No filter: {{greeting}}<br>
|
||||
Reverse: {{greeting|reverse}}<br>
|
||||
Reverse + uppercase: {{greeting|reverse:true}}<br>
|
||||
</div>
|
||||
</file>
|
||||
|
||||
function Ctrl($scope) {
|
||||
$scope.greeting = 'hello';
|
||||
}
|
||||
</script>
|
||||
<file name="script.js">
|
||||
angular.module('MyReverseModule', []).
|
||||
filter('reverse', function() {
|
||||
return function(input, uppercase) {
|
||||
var out = "";
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
out = input.charAt(i) + out;
|
||||
}
|
||||
// conditional based on optional argument
|
||||
if (uppercase) {
|
||||
out = out.toUpperCase();
|
||||
}
|
||||
return out;
|
||||
};
|
||||
});
|
||||
|
||||
<div ng-controller="Ctrl">
|
||||
<input ng-model="greeting" type="greeting"><br>
|
||||
No filter: {{greeting}}<br>
|
||||
Reverse: {{greeting|reverse}}<br>
|
||||
Reverse + uppercase: {{greeting|reverse:true}}<br>
|
||||
</div>
|
||||
</doc:source>
|
||||
</doc:example>
|
||||
function Ctrl($scope) {
|
||||
$scope.greeting = 'hello';
|
||||
}
|
||||
</file>
|
||||
</example>
|
||||
|
||||
## Testing custom filters
|
||||
|
||||
|
||||
@@ -16,38 +16,38 @@ The key directive in understanding two-way data-binding is {@link ng.directive:n
|
||||
The `ngModel` directive provides the two-way data-binding by synchronizing the model to the view, as well as view to the model.
|
||||
In addition it provides an {@link ngModel.NgModelController API} for other directives to augment its behavior.
|
||||
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
<div ng-controller="Controller">
|
||||
<form novalidate class="simple-form">
|
||||
Name: <input type="text" ng-model="user.name" /><br />
|
||||
E-mail: <input type="email" ng-model="user.email" /><br />
|
||||
Gender: <input type="radio" ng-model="user.gender" value="male" />male
|
||||
<input type="radio" ng-model="user.gender" value="female" />female<br />
|
||||
<button ng-click="reset()">RESET</button>
|
||||
<button ng-click="update(user)">SAVE</button>
|
||||
</form>
|
||||
<pre>form = {{user | json}}</pre>
|
||||
<pre>master = {{master | json}}</pre>
|
||||
</div>
|
||||
<example>
|
||||
<file name="index.html">
|
||||
<div ng-controller="Controller">
|
||||
<form novalidate class="simple-form">
|
||||
Name: <input type="text" ng-model="user.name" /><br />
|
||||
E-mail: <input type="email" ng-model="user.email" /><br />
|
||||
Gender: <input type="radio" ng-model="user.gender" value="male" />male
|
||||
<input type="radio" ng-model="user.gender" value="female" />female<br />
|
||||
<button ng-click="reset()">RESET</button>
|
||||
<button ng-click="update(user)">SAVE</button>
|
||||
</form>
|
||||
<pre>form = {{user | json}}</pre>
|
||||
<pre>master = {{master | json}}</pre>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function Controller($scope) {
|
||||
$scope.master = {};
|
||||
<script>
|
||||
function Controller($scope) {
|
||||
$scope.master = {};
|
||||
|
||||
$scope.update = function(user) {
|
||||
$scope.master = angular.copy(user);
|
||||
};
|
||||
$scope.update = function(user) {
|
||||
$scope.master = angular.copy(user);
|
||||
};
|
||||
|
||||
$scope.reset = function() {
|
||||
$scope.user = angular.copy($scope.master);
|
||||
};
|
||||
$scope.reset = function() {
|
||||
$scope.user = angular.copy($scope.master);
|
||||
};
|
||||
|
||||
$scope.reset();
|
||||
}
|
||||
</script>
|
||||
</doc:source>
|
||||
</doc:example>
|
||||
$scope.reset();
|
||||
}
|
||||
</script>
|
||||
</file>
|
||||
</example>
|
||||
|
||||
|
||||
Note that `novalidate` is used to disable browser's native form validation.
|
||||
@@ -67,47 +67,47 @@ The following example uses the CSS to display validity of each form control.
|
||||
In the example both `user.name` and `user.email` are required, but are rendered with red background only when they are dirty.
|
||||
This ensures that the user is not distracted with an error until after interacting with the control, and failing to satisfy its validity.
|
||||
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
<div ng-controller="Controller">
|
||||
<form novalidate class="css-form">
|
||||
Name:
|
||||
<input type="text" ng-model="user.name" required /><br />
|
||||
E-mail: <input type="email" ng-model="user.email" required /><br />
|
||||
Gender: <input type="radio" ng-model="user.gender" value="male" />male
|
||||
<input type="radio" ng-model="user.gender" value="female" />female<br />
|
||||
<button ng-click="reset()">RESET</button>
|
||||
<button ng-click="update(user)">SAVE</button>
|
||||
</form>
|
||||
</div>
|
||||
<example>
|
||||
<file name="index.html">
|
||||
<div ng-controller="Controller">
|
||||
<form novalidate class="css-form">
|
||||
Name:
|
||||
<input type="text" ng-model="user.name" required /><br />
|
||||
E-mail: <input type="email" ng-model="user.email" required /><br />
|
||||
Gender: <input type="radio" ng-model="user.gender" value="male" />male
|
||||
<input type="radio" ng-model="user.gender" value="female" />female<br />
|
||||
<button ng-click="reset()">RESET</button>
|
||||
<button ng-click="update(user)">SAVE</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<style type="text/css">
|
||||
.css-form input.ng-invalid.ng-dirty {
|
||||
background-color: #FA787E;
|
||||
}
|
||||
<style type="text/css">
|
||||
.css-form input.ng-invalid.ng-dirty {
|
||||
background-color: #FA787E;
|
||||
}
|
||||
|
||||
.css-form input.ng-valid.ng-dirty {
|
||||
background-color: #78FA89;
|
||||
}
|
||||
</style>
|
||||
.css-form input.ng-valid.ng-dirty {
|
||||
background-color: #78FA89;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function Controller($scope) {
|
||||
$scope.master = {};
|
||||
<script>
|
||||
function Controller($scope) {
|
||||
$scope.master = {};
|
||||
|
||||
$scope.update = function(user) {
|
||||
$scope.master = angular.copy(user);
|
||||
};
|
||||
$scope.update = function(user) {
|
||||
$scope.master = angular.copy(user);
|
||||
};
|
||||
|
||||
$scope.reset = function() {
|
||||
$scope.user = angular.copy($scope.master);
|
||||
};
|
||||
$scope.reset = function() {
|
||||
$scope.user = angular.copy($scope.master);
|
||||
};
|
||||
|
||||
$scope.reset();
|
||||
}
|
||||
</script>
|
||||
</doc:source>
|
||||
</doc:example>
|
||||
$scope.reset();
|
||||
}
|
||||
</script>
|
||||
</file>
|
||||
</example>
|
||||
|
||||
|
||||
|
||||
@@ -130,54 +130,54 @@ This allows us to extend the above example with these features:
|
||||
- SAVE button is enabled only if form has some changes and is valid
|
||||
- custom error messages for `user.email` and `user.agree`
|
||||
|
||||
<doc:example>
|
||||
<doc:source>
|
||||
<div ng-controller="Controller">
|
||||
<form name="form" class="css-form" novalidate>
|
||||
Name:
|
||||
<input type="text" ng-model="user.name" name="uName" required /><br />
|
||||
E-mail:
|
||||
<input type="email" ng-model="user.email" name="uEmail" required/><br />
|
||||
<div ng-show="form.uEmail.$dirty && form.uEmail.$invalid">Invalid:
|
||||
<span ng-show="form.uEmail.$error.required">Tell us your email.</span>
|
||||
<span ng-show="form.uEmail.$error.email">This is not a valid email.</span>
|
||||
<example>
|
||||
<file name="index.html">
|
||||
<div ng-controller="Controller">
|
||||
<form name="form" class="css-form" novalidate>
|
||||
Name:
|
||||
<input type="text" ng-model="user.name" name="uName" required /><br />
|
||||
E-mail:
|
||||
<input type="email" ng-model="user.email" name="uEmail" required/><br />
|
||||
<div ng-show="form.uEmail.$dirty && form.uEmail.$invalid">Invalid:
|
||||
<span ng-show="form.uEmail.$error.required">Tell us your email.</span>
|
||||
<span ng-show="form.uEmail.$error.email">This is not a valid email.</span>
|
||||
</div>
|
||||
|
||||
Gender: <input type="radio" ng-model="user.gender" value="male" />male
|
||||
<input type="radio" ng-model="user.gender" value="female" />female<br />
|
||||
|
||||
<input type="checkbox" ng-model="user.agree" name="userAgree" required />
|
||||
I agree: <input ng-show="user.agree" type="text" ng-model="user.agreeSign"
|
||||
required /><br />
|
||||
<div ng-show="!user.agree || !user.agreeSign">Please agree and sign.</div>
|
||||
|
||||
<button ng-click="reset()" ng-disabled="isUnchanged(user)">RESET</button>
|
||||
<button ng-click="update(user)"
|
||||
ng-disabled="form.$invalid || isUnchanged(user)">SAVE</button>
|
||||
</form>
|
||||
</div>
|
||||
</file>
|
||||
|
||||
Gender: <input type="radio" ng-model="user.gender" value="male" />male
|
||||
<input type="radio" ng-model="user.gender" value="female" />female<br />
|
||||
<file name="script.js">
|
||||
function Controller($scope) {
|
||||
$scope.master = {};
|
||||
|
||||
<input type="checkbox" ng-model="user.agree" name="userAgree" required />
|
||||
I agree: <input ng-show="user.agree" type="text" ng-model="user.agreeSign"
|
||||
required /><br />
|
||||
<div ng-show="!user.agree || !user.agreeSign">Please agree and sign.</div>
|
||||
$scope.update = function(user) {
|
||||
$scope.master = angular.copy(user);
|
||||
};
|
||||
|
||||
<button ng-click="reset()" ng-disabled="isUnchanged(user)">RESET</button>
|
||||
<button ng-click="update(user)"
|
||||
ng-disabled="form.$invalid || isUnchanged(user)">SAVE</button>
|
||||
</form>
|
||||
</div>
|
||||
$scope.reset = function() {
|
||||
$scope.user = angular.copy($scope.master);
|
||||
};
|
||||
|
||||
<script>
|
||||
function Controller($scope) {
|
||||
$scope.master = {};
|
||||
$scope.isUnchanged = function(user) {
|
||||
return angular.equals(user, $scope.master);
|
||||
};
|
||||
|
||||
$scope.update = function(user) {
|
||||
$scope.master = angular.copy(user);
|
||||
};
|
||||
|
||||
$scope.reset = function() {
|
||||
$scope.user = angular.copy($scope.master);
|
||||
};
|
||||
|
||||
$scope.isUnchanged = function(user) {
|
||||
return angular.equals(user, $scope.master);
|
||||
};
|
||||
|
||||
$scope.reset();
|
||||
}
|
||||
</script>
|
||||
</doc:source>
|
||||
</doc:example>
|
||||
$scope.reset();
|
||||
}
|
||||
</file>
|
||||
</example>
|
||||
|
||||
|
||||
|
||||
@@ -209,72 +209,72 @@ In the following example we create two directives.
|
||||
Note that we can't use input type `number` here as HTML5 browsers would not allow the user to type what it would consider an invalid number such as `1,2`.
|
||||
|
||||
|
||||
<doc:example module="form-example1">
|
||||
<doc:source>
|
||||
<div ng-controller="Controller">
|
||||
<form name="form" class="css-form" novalidate>
|
||||
<div>
|
||||
Size (integer 0 - 10):
|
||||
<input type="number" ng-model="size" name="size"
|
||||
min="0" max="10" integer />{{size}}<br />
|
||||
<span ng-show="form.size.$error.integer">This is not valid integer!</span>
|
||||
<span ng-show="form.size.$error.min || form.size.$error.max">
|
||||
The value must be in range 0 to 10!</span>
|
||||
<example module="form-example1">
|
||||
<file name="index.html">
|
||||
<div ng-controller="Controller">
|
||||
<form name="form" class="css-form" novalidate>
|
||||
<div>
|
||||
Size (integer 0 - 10):
|
||||
<input type="number" ng-model="size" name="size"
|
||||
min="0" max="10" integer />{{size}}<br />
|
||||
<span ng-show="form.size.$error.integer">This is not valid integer!</span>
|
||||
<span ng-show="form.size.$error.min || form.size.$error.max">
|
||||
The value must be in range 0 to 10!</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Length (float):
|
||||
<input type="text" ng-model="length" name="length" smart-float />
|
||||
{{length}}<br />
|
||||
<span ng-show="form.length.$error.float">
|
||||
This is not a valid float number!</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</file>
|
||||
|
||||
<div>
|
||||
Length (float):
|
||||
<input type="text" ng-model="length" name="length" smart-float />
|
||||
{{length}}<br />
|
||||
<span ng-show="form.length.$error.float">
|
||||
This is not a valid float number!</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<file name="script.js">
|
||||
var app = angular.module('form-example1', []);
|
||||
|
||||
<script>
|
||||
var app = angular.module('form-example1', []);
|
||||
var INTEGER_REGEXP = /^\-?\d+$/;
|
||||
app.directive('integer', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, elm, attrs, ctrl) {
|
||||
ctrl.$parsers.unshift(function(viewValue) {
|
||||
if (INTEGER_REGEXP.test(viewValue)) {
|
||||
// it is valid
|
||||
ctrl.$setValidity('integer', true);
|
||||
return viewValue;
|
||||
} else {
|
||||
// it is invalid, return undefined (no model update)
|
||||
ctrl.$setValidity('integer', false);
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var INTEGER_REGEXP = /^\-?\d+$/;
|
||||
app.directive('integer', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, elm, attrs, ctrl) {
|
||||
ctrl.$parsers.unshift(function(viewValue) {
|
||||
if (INTEGER_REGEXP.test(viewValue)) {
|
||||
// it is valid
|
||||
ctrl.$setValidity('integer', true);
|
||||
return viewValue;
|
||||
} else {
|
||||
// it is invalid, return undefined (no model update)
|
||||
ctrl.$setValidity('integer', false);
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var FLOAT_REGEXP = /^\-?\d+((\.|\,)\d+)?$/;
|
||||
app.directive('smartFloat', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, elm, attrs, ctrl) {
|
||||
ctrl.$parsers.unshift(function(viewValue) {
|
||||
if (FLOAT_REGEXP.test(viewValue)) {
|
||||
ctrl.$setValidity('float', true);
|
||||
return parseFloat(viewValue.replace(',', '.'));
|
||||
} else {
|
||||
ctrl.$setValidity('float', false);
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
</script>
|
||||
</doc:source>
|
||||
</doc:example>
|
||||
var FLOAT_REGEXP = /^\-?\d+((\.|\,)\d+)?$/;
|
||||
app.directive('smartFloat', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, elm, attrs, ctrl) {
|
||||
ctrl.$parsers.unshift(function(viewValue) {
|
||||
if (FLOAT_REGEXP.test(viewValue)) {
|
||||
ctrl.$setValidity('float', true);
|
||||
return parseFloat(viewValue.replace(',', '.'));
|
||||
} else {
|
||||
ctrl.$setValidity('float', false);
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
|
||||
|
||||
# Implementing custom form controls (using `ngModel`)
|
||||
@@ -290,40 +290,40 @@ See {@link guide/directive $compileProvider.directive} for more info.
|
||||
|
||||
The following example shows how to add two-way data-binding to contentEditable elements.
|
||||
|
||||
<doc:example module="form-example2">
|
||||
<doc:source>
|
||||
<script>
|
||||
angular.module('form-example2', []).directive('contenteditable', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, elm, attrs, ctrl) {
|
||||
// view -> model
|
||||
elm.on('blur', function() {
|
||||
scope.$apply(function() {
|
||||
ctrl.$setViewValue(elm.html());
|
||||
});
|
||||
});
|
||||
<example module="form-example2">
|
||||
<file name="index.html">
|
||||
<div contentEditable="true" ng-model="content" title="Click to edit">Some</div>
|
||||
<pre>model = {{content}}</pre>
|
||||
|
||||
// model -> view
|
||||
ctrl.$render = function() {
|
||||
elm.html(ctrl.$viewValue);
|
||||
};
|
||||
|
||||
// load init value from DOM
|
||||
ctrl.$setViewValue(elm.html());
|
||||
<style type="text/css">
|
||||
div[contentEditable] {
|
||||
cursor: pointer;
|
||||
background-color: #D0D0D0;
|
||||
}
|
||||
};
|
||||
});
|
||||
</script>
|
||||
</style>
|
||||
</file>
|
||||
|
||||
<div contentEditable="true" ng-model="content" title="Click to edit">Some</div>
|
||||
<pre>model = {{content}}</pre>
|
||||
<file name="script.js">
|
||||
angular.module('form-example2', []).directive('contenteditable', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
link: function(scope, elm, attrs, ctrl) {
|
||||
// view -> model
|
||||
elm.on('blur', function() {
|
||||
scope.$apply(function() {
|
||||
ctrl.$setViewValue(elm.html());
|
||||
});
|
||||
});
|
||||
|
||||
<style type="text/css">
|
||||
div[contentEditable] {
|
||||
cursor: pointer;
|
||||
background-color: #D0D0D0;
|
||||
}
|
||||
</style>
|
||||
</doc:source>
|
||||
</doc:example>
|
||||
// model -> view
|
||||
ctrl.$render = function() {
|
||||
elm.html(ctrl.$viewValue);
|
||||
};
|
||||
|
||||
// load init value from DOM
|
||||
ctrl.$setViewValue(elm.html());
|
||||
}
|
||||
};
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
|
||||
@@ -27,7 +27,7 @@ To make your Angular application work on IE please make sure that:
|
||||
[JSON2](https://github.com/douglascrockford/JSON-js) or
|
||||
[JSON3](http://bestiejs.github.com/json3/) polyfills for this.
|
||||
|
||||
```html
|
||||
```html
|
||||
<!doctype html>
|
||||
<html xmlns:ng="http://angularjs.org">
|
||||
<head>
|
||||
@@ -43,7 +43,7 @@ To make your Angular application work on IE please make sure that:
|
||||
|
||||
2. add `id="ng-app"` to the root element in conjunction with `ng-app` attribute
|
||||
|
||||
```html
|
||||
```html
|
||||
<!doctype html>
|
||||
<html xmlns:ng="http://angularjs.org" id="ng-app" ng-app="optionalModuleName">
|
||||
...
|
||||
@@ -55,7 +55,7 @@ To make your Angular application work on IE please make sure that:
|
||||
|
||||
4. if you **do use** custom element tags, then you must take these steps to make IE 8 and below happy:
|
||||
|
||||
```html
|
||||
```html
|
||||
<!doctype html>
|
||||
<html xmlns:ng="http://angularjs.org" id="ng-app" ng-app="optionalModuleName">
|
||||
<head>
|
||||
|
||||
@@ -26,26 +26,26 @@ Important things to notice:
|
||||
* Notice the reference to the `myApp` module in the `<html ng-app="myApp">`, it is what
|
||||
bootstraps the app using your module.
|
||||
|
||||
<doc:example module='myApp'>
|
||||
<doc:source>
|
||||
<script>
|
||||
// declare a module
|
||||
var myAppModule = angular.module('myApp', []);
|
||||
|
||||
// configure the module.
|
||||
// in this example we will create a greeting filter
|
||||
myAppModule.filter('greet', function() {
|
||||
return function(name) {
|
||||
return 'Hello, ' + name + '!';
|
||||
};
|
||||
});
|
||||
|
||||
</script>
|
||||
<example module='myApp'>
|
||||
<file name="index.html">
|
||||
<div>
|
||||
{{ 'World' | greet }}
|
||||
</div>
|
||||
</doc:source>
|
||||
</doc:example>
|
||||
</file>
|
||||
|
||||
<file name="script.js">
|
||||
// declare a module
|
||||
var myAppModule = angular.module('myApp', []);
|
||||
|
||||
// configure the module.
|
||||
// in this example we will create a greeting filter
|
||||
myAppModule.filter('greet', function() {
|
||||
return function(name) {
|
||||
return 'Hello, ' + name + '!';
|
||||
};
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
|
||||
|
||||
|
||||
@@ -67,49 +67,50 @@ that are relevant to tests.
|
||||
|
||||
The above is only a suggestion, so feel free to tailor it to your needs.
|
||||
|
||||
<doc:example module='xmpl'>
|
||||
<doc:source>
|
||||
<script>
|
||||
angular.module('xmpl.service', []).
|
||||
value('greeter', {
|
||||
salutation: 'Hello',
|
||||
localize: function(localization) {
|
||||
this.salutation = localization.salutation;
|
||||
},
|
||||
greet: function(name) {
|
||||
return this.salutation + ' ' + name + '!';
|
||||
}
|
||||
}).
|
||||
value('user', {
|
||||
load: function(name) {
|
||||
this.name = name;
|
||||
}
|
||||
});
|
||||
|
||||
angular.module('xmpl.directive', []);
|
||||
|
||||
angular.module('xmpl.filter', []);
|
||||
|
||||
angular.module('xmpl', ['xmpl.service', 'xmpl.directive', 'xmpl.filter']).
|
||||
run(function(greeter, user) {
|
||||
// This is effectively part of the main method initialization code
|
||||
greeter.localize({
|
||||
salutation: 'Bonjour'
|
||||
});
|
||||
user.load('World');
|
||||
})
|
||||
|
||||
|
||||
// A Controller for your app
|
||||
var XmplController = function($scope, greeter, user) {
|
||||
$scope.greeting = greeter.greet(user.name);
|
||||
}
|
||||
</script>
|
||||
<example module='xmpl'>
|
||||
<file name="index.html">
|
||||
<div ng-controller="XmplController">
|
||||
{{ greeting }}!
|
||||
</div>
|
||||
</doc:source>
|
||||
</doc:example>
|
||||
</file>
|
||||
|
||||
<file name="script.js">
|
||||
angular.module('xmpl.service', []).
|
||||
value('greeter', {
|
||||
salutation: 'Hello',
|
||||
localize: function(localization) {
|
||||
this.salutation = localization.salutation;
|
||||
},
|
||||
greet: function(name) {
|
||||
return this.salutation + ' ' + name + '!';
|
||||
}
|
||||
}).
|
||||
value('user', {
|
||||
load: function(name) {
|
||||
this.name = name;
|
||||
}
|
||||
});
|
||||
|
||||
angular.module('xmpl.directive', []);
|
||||
|
||||
angular.module('xmpl.filter', []);
|
||||
|
||||
angular.module('xmpl', ['xmpl.service', 'xmpl.directive', 'xmpl.filter']).
|
||||
run(function(greeter, user) {
|
||||
// This is effectively part of the main method initialization code
|
||||
greeter.localize({
|
||||
salutation: 'Bonjour'
|
||||
});
|
||||
user.load('World');
|
||||
});
|
||||
|
||||
|
||||
// A Controller for your app
|
||||
var XmplController = function($scope, greeter, user) {
|
||||
$scope.greeting = greeter.greet(user.name);
|
||||
};
|
||||
</file>
|
||||
</example>
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user