Skip to content

Instantly share code, notes, and snippets.

@IskenHuang
Created September 27, 2013 09:00
Show Gist options
  • Save IskenHuang/6725917 to your computer and use it in GitHub Desktop.
Save IskenHuang/6725917 to your computer and use it in GitHub Desktop.

page

137 ~ 152

$location

The $location service is a wrapper around the window.location that is present in any browser.

global status

The minute you have global state in your application, testing, maintaining and working with it becomes a hassle.

API

window.location gives you total access to the contents of the browser location.

AngularJS integration

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.

HTML5 integration

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();
};

$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!'

  1. DO NOT call it all the time. Cause and exception. So 'better safe then sorry' is not the approach you want to use.
  2. DO CALL it when controls outside of AngularJS
  3. 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);
    }
};
Table 7-1 function on the $location service
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')
Search() setter has a few modes of operation
  • 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.

HTML5 mode and hashbang mode in route provider

HTML5Mode

A boolean value. $location service works in HTML5 mode or not.

hashPrefix

default is empty string ''. If the hashPrefix is set to '!', then Angular uses that we call Hashbang URLs.

sample
legacy browser

http://www.trendmicro.com/#!/foo?bar=123#baz

HTML5

http://www.trendmicro.com/foo?bar=123#baz

  • location.path() = '/foo'
  • location.search() = 'bar=123'
  • location.hash() = 'baz'

Service configuration

single page design

link rewriting

  • 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

Relative Links

url base in head add <base href="/my-base">

AngularJS module Methods

start app from minifold

  • declarative
  • modular
  • easy testing

(Ch4. with RequireJS example)

Loading and Dependencies

Config block

only providers and constants can be injected into Config blocks. Server that may or may not have been initialized cannot be injected.

Run block

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.

Convenience Mehods

Table 7-2 Module configuration methods

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

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');

The Service

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

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');
});

WARNING

  • 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.

Communicating between scopes with $on, $emit and $broadcast

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();
    }
})

table 7-3 Event object properties and mehtods

事件属性 目的
event.targetScope 发出或者传播原始事件的作用域
event.currentScope 目前正在处理的事件的作用域
event.name 事件名称
event.stopPropagation() 一个防止事件进一步传播(冒泡/捕获)的函数(这只适用于使用`$emit`发出的事件)
event.preventDefault() 这个方法实际上不会做什么事,但是会设置`defaultPrevented`为true。直到事件监听器的实现者采取行动之前它才会检查`defaultPrevented`的值。
event.defaultPrevented 如果调用了`preventDefault`则为true

Cookies

  • $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);
    }
}

Internationalization and localization (i18n & l10n)

angular support used 'ngPluralize'

What Can I Do in AngularJS

  • currency
  • data/time
  • number

How Do I Get It All Working

Index.html changes

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 localized rule sets

Create an angular.js file for each supported locale, like (angular_en-US.js and angular_zh-CN.js).

Sourcing the localized

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

Common gotchas

Translation length

  • en-US : June 24, 1988.
  • Spanish : 24 de junio de 1988

Timezones

Sanitizing HTML & the Sanitize Module

  • ngSanitize
    • $sanitize

DEMO

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment