browser-sync start -server -directory --files "**/*"
DIController.$inject = ['$scope', '$filter']
- $scope.$digest
- $scope.$apply
- $timeout
- 2-way: ng-model
- 1-way: {{prop}}
- 1-time: {{:: prop}}
$index in ng-repeat
"item in collection | fiilter : searchString"
- Property can mask parent object
- Object will not mask parent object
- Constroller as Syntax will not mask parent object.
HTML:
<div ng-controller='MyController2 as **ctrl1**'>
value: {{ ctrl1.value }}
</div>
JS:
function MyController2() {
**var ctrl1 = this**;
ctrl1.value = 1;
}
- Controller should not have business logic and should not share data with other controllers.
- Service is sington and can share data between multiple controllers
angular.module('app',[])
.controller('ctrl',Ctrl)
.service('customService',CustomerService);
function CustomerService {
var srevice = this;
...
// Expose data or fucntion by service.xxx
}
Register factory with controller
angular.module('app',[])
.controller('ctrl',Ctrl)
.factory('customService',CustomerService);
Define factory to return function:
function CustomerService() {
var factory = fucntion (){
return new SomeService();
};
return factory;
}
var someSrv= CustomerService();
Define factory to return object literal
function CustomerService() {
var factory = {
getSomeService:fucntion (){
return new SomeService();
}
};
return factory;
}
var someSrv= CustomerService.getSomeservice();
angular.module('app',[])
.controller('ctrl',Ctrl)
.provider('Service',ServiceProvider)
.config(Config);
function ServiceProvider(){
var provider = this;
provider.config = {...};
provider.$get = function () {
var service = new service(provider.config.prop);
return service;
};
}
To configure a service, it must be injected into the function passed into the .config() function with the extra string "Provider" appended to the String name the provider was declared with. (passed into .provider as the first argument).
- ng-if will remove the div from DOM
- ng-hide/ng-show will not remove the div from DOM, but just show or hide the div (display: none !important)
fucntion asyncFunc() {
var deferred = **$q.defer()**;
if(...) { deferred.resolve(result); }
else { deferred.reject(error); }
return deferred.promise;
}
var promise = sync Function();
promise.then(function(result) {
// do something with result
},
function (error) {
// do something with error
});
$q.all([promise1, promise2])
.then(function(result) {
// do something with result
})
.catch(function(error) {
// handle error
});
$http({
method: "GET,
url: "http://someurl",
params: { param1: "value1" } // value get url eoncoded automatically, so don't put params in the url.
...
}).then(
function success(response) {
// do something with response.data
},
function error(response) {
// do something with error response
}
);
angular.module('app',[])
.controller('MyCtrl', MyCtrl)
.directive('myTag', MyTag); // MyTag is the Directive Definition Objedct (DDO)
MyTag.$inject = [...]
function MyTag(...) {
var ddo = {
template: 'Hello World!'
...
};
return ddo;
}
Name match in the html: <my-tag></my-tag>
with in code: myTag
- Use 'E' for element when directive has content along with possible behavior
- Use 'A' for attribute when directive has no content and only extends the behaviors of host element
=attributeMame : bi-directional binding with HTML template attribute named 'attributeMame' = : bi-directional binding with the same named attribute in HTML template (denormalized name) e.g. my-prop =? : attbiute is optional @: one-way binding, the outter DOM property changes impact the inner directive property, but inner changes to the property myProp does not impact outter attribute value.
fucntion MyDirective() {
var ddo = {
scope: {
myProp: '=attributeName' // HTML template attibute name
myProp1: '='
}
...
};
return ddo;
}
<my-directive my-prop="outterProp"></my-directive>
fucntion MyDirective() {
var ddo = {
scope: {
myProp: '<' // Oneway binding, watches only the parent property, not the property inside directive
},
controller: ControllerFunction,
bindToController: true, // Attach declated scope properties to controller instance instead of directly to $scope
controllerAs: 'myCtrl', // Use 'myCtrl' in template to refer to controller instance
templateUrl: 'template.html'
};
return ddo;
}
Note:
- one-way binding "<" is preferred to save resource instead of two-way binding with "=".
- one-way binding can not prevent innder directive logic change the perperty of passed-in object and imapct the outter property. As oject is passed as reference.
Parent controller manapulates the data, not the inner directive. Innder directive can call a method passed-in as reference from parent controller.
directive:
function MyDirective(){
var ddo = {
scope: {
myMethod: '&method'
},
...
templateUrl: 'template.html'
};
return ddo;
}
controller's html:
<div ng-controller = "Controller as ctrl">
<my-directive method = "ctrl.method(myArg)">
</my-directive>
</div>
directive's template html:
<button ng-click = "dirCtrl.myMethod({myArg:'v1'});">
Remove Item
</button>
- DOM manipulation is usually done inside the link function
- Link function does not support injection, inject them into directive instead.
Declare Link Function
function MyDirective(){
var ddo = {
scope: {...},
**link: LinkFunction**,
...
templateUrl: 'template.html'
};
return ddo;
}
function LinkFunction(scope, element, attrs, contrllers) {
}
- scope is the exact $scope inside directive's controller
- element repsents the top level element of the directive. It is either jqLite oject or JQuery object( if jQuery is included)
- Set transclude to true
function MyDirective(){
var ddo = {
scope: {...},
transclude: true,
...
templateUrl: 'template.html'
};
return ddo;
}
- Wrap some parent content Interpolation will be done in the parent controller's context, not the directive's context.
<my-directive>
{{ctrl.someProp}}
</my-directive>
- ng-transclude to place wrapped content
<div ng-transclude></div>