137 ~ 152
The $location service is a wrapper around the window.location that is present in any browser.
The minute you have global state in your application, testing, maintaining and working with it becomes a hassle.
window.location gives you total access to the contents of the browser location.
If you use $locationm you can use it however you want. But with window.location, you would have to be responsible for nothfying AngularJS of changesm and listen to changes as well.
The $location service is smart enough to realize when HTML5 APIs are available within a browser and use them.
// Assume that the datepicker calls $scope.dateSelected with the date
$scope.dateSelected = function(dateTxt) {
$location.path('/filteredResults?startDate=' + dataTxt);
// If this were being done in the callback for an external library, like jQuery, then we would have to
$scope.$apply();
};
scope.$apply just take note, but does nothing. That is why we have to call scope.$apply to tell it, 'Hey! You need to do this right now, and not wait!'
- DO NOT call it all the time. Cause and exception. So 'better safe then sorry' is not the approach you want to use.
- DO CALL it when controls outside of AngularJS
- Whenever possible, execute your code or function by passing it to $apply, rather than executing the function and then call $apply().
Consider using something like safeApply
$scope.safeApply = function(fn) {
var phase = this.$root.$phase;
if( phase == '$apply' || phase == '$digest') {
if(fn && (typeof(fn) === 'function')){
fn();
}
}else{
this.$apply(fn);
}
};
Getter Function | Getter Value | Setter Function |
---|---|---|
absUrl() | http://www.host.com/base/index.html#!/path?param1=value1#hashValue, | N/A |
hash() | hashValue | hash('newHash') |
host() | www.host.com | N/A |
path() | /path | path('/newPath') |
protocol() | http | N/A |
search() | {'a':'b'} | search({'c':'def'}) |
url() | /path?param1=value1?hashValue | url('/newPath?p2=v2') |
- Calling search(ojbect) with an object< string, string> basically denotes all the parameters and their values.
- CAlling search(string) will set the URL params as q=String directly in the URL.
- Call search(param, value) with a string and calue set a particular search parameter in the URL.
A boolean value. $location service works in HTML5 mode or not.
default is empty string ''. If the hashPrefix is set to '!', then Angular uses that we call Hashbang URLs.
http://www.trendmicro.com/#!/foo?bar=123#baz
http://www.trendmicro.com/foo?bar=123#baz
- location.path() = '/foo'
- location.search() = 'bar=123'
- location.hash() = 'baz'
single page design
- Links that contain a target element such as the following
- Absolute links going to a different domain
- Links starting with a different base path when one is already defind
url base in head add <base href="/my-base">
- declarative
- modular
- easy testing
(Ch4. with RequireJS example)
only providers and constants can be injected into Config blocks. Server that may or may not have been initialized cannot be injected.
only instances and constants can be injected into Run blocks. The Run block is the closest you are going to find to a main method in AngularJS.
API方法 | 描述 |
---|---|
config(configFn) | 模块加载时使用这个方法注册模块需要做的工作。 |
constant(name, object) | 这个首先发生,因此你可以在这里声明所有的常量`app-wide`,和声明所有可用的配置(也就是列表中的第一个方法)以及方法实例(从这里获取所有的方法,如控制器,服务等等). |
controller(name, constructor) | 我们已经看过了很多控制器的例子,它主要用于设置一个控制器。 |
directive(name, directiveFactory) | 正如第6章所讨论的,它允许你为应用程序创建指令。 |
filter(name, filterFactory) | 允许你创建命名AngularJS过滤器,正如第6章所讨论的。 |
run(initializationFn) | 使用这个方法在注入设置完成时处理你要执行的工作,也就是将你的应用程序展示给用户之前。 |
value(name, object) | 允许跨应用程序注入值。 |
service(name, serviceFactory) | 下一节中讨论。 |
factory(name, factoryFn) | 下一节中讨论。 |
provider(name, providerFn) | 下一节中讨论。 |
The Factory API call is used whenever we have a class or object that needs some amount of logic or parameters before it can be initialized.
function Greeter(salutation) {
this.greet = function(name) {
return salutation + ' ' + name;
}
}
// factory
myApp.factory('greeter', function(salut){
return new Greeter(salut);
});
// called as
var myGreeter = greeter('halo');
Service is that the Factory invokes the function passed to it and return a result
myApp.service('greeter', Greeter);
Every time I asked for a greeter, AngularJS would call the new Greeter() and return that
The Provider combines both the Factory and the Service, and also throws in the benefit of being able to configure the Provider function before the injection system is fully in place (in the config blocks, that is).
myApp.provider('greeter', function() {
var salutation = 'hello';
this.setSalutation = function(s) {
salutation = s;
}
funtion Greeter(a) {
this.greet = function() {
return salutation + ' ' + a;
}
}
this.$get = function(a) {
return new Greeter(a);
}
});
// called as
var myApp = angular.module( myApp, []).config(function(greeterProvider){
greeterProvider.salutation('Randy');
});
- angular.module('myApp', […])
- angular.module('myApp')
- The difference is that the first creates a new angular module, pulling in the module dependencies listed in the square brackets. The second uses the existing module that has already been defined by first call.
How do you communicate between scopes? One option is creating a service that is singleton in the scope of the app, and processing all inter-scope communication through that service.
You cannot generally broadcast an event to all watching scope.
// Here is an example where our scope on any Star System is waiting and waiting and watching for an event we call 'plantDestoryed.'
scope.$on('planeDestroyed', function(event, galaxy, planet) {
// Custom event, so whet plant was destroyed
scope.alertNearByPlanets( galaxy, planet);
});
//parent star system
scope.$emit('planeDestroyed', scope.myGalaxy, scope.myPlanet);
// $emit communicates only upwards from its current scope
scope.$emit('planeDestroyed', targetSystem);
scope.$on('planeDestroyed', function(event, targetSystem) {
if(scope.mySystem === targetStstem) {
scope.selfDestruct();
}
})
事件属性 | 目的 |
---|---|
event.targetScope | 发出或者传播原始事件的作用域 |
event.currentScope | 目前正在处理的事件的作用域 |
event.name | 事件名称 |
event.stopPropagation() | 一个防止事件进一步传播(冒泡/捕获)的函数(这只适用于使用`$emit`发出的事件) |
event.preventDefault() | 这个方法实际上不会做什么事,但是会设置`defaultPrevented`为true。直到事件监听器的实现者采取行动之前它才会检查`defaultPrevented`的值。 |
event.defaultPrevented | 如果调用了`preventDefault`则为true |
-
$cookie
and $cookieStore API play nice with HTML5 cookies. -
$cookie
is simple object. keys and values. and working with $cookies level. working with cookie level would mean doing string manipulation and parsing yourself, and converting data to and from objects. -
$cookieStore
, which provides a programmatic way of writing and remove cookies. -
$cookieStore
sample
function SearchController($scope, $cookieStore) {
$scope.search = function(text) {
// Do the search here
...
// Get the past results, or initialize an empty array if nothing found
var pastSearches = $cookieStore.get('myapp.past.searches') || [];
if(pastSearches.length > 5) {
pastSearches = pastSearches.splice(0);
}
pastSearches.push(text);
$cookieStore.put('myapp.past.searches', pastSearches);
}
}
angular support used 'ngPluralize'
- currency
- data/time
- number
your server also needs to know which index.html it has to provide, depending on the user's locale preferences (this could also be triggered from a client-side change, when the user changes his locale).
Create an angular.js file for each supported locale, like (angular_en-US.js and angular_zh-CN.js).
ensuring that your localized index.html refers to the localized rule set instead of the original 'angular.js' file. So 'index_en-US.html' should use 'angular-en_US.js' and not angular.js
- en-US : June 24, 1988.
- Spanish : 24 de junio de 1988
- ngSanitize
$sanitize