angular 1.3
one time binding
<tr ng-repeat="class in ::classes">
<td></td>
</tr>
ng-repeat
syntax means if we add or remove items from classes
, it will not affect the underlying classes
array on the scope
onetime binding can also be used in directive.
<my-directive name="::variable"></my-driective>
angular.module('text').directive('myDirective', function() {
return {
template: '',
scope: {
name: '='
}
};
})
disabling scope info
when in production enviroment disable debugInfo can improve proformance
angular.module('app').config(function($compileProvider) {
$compileProvider.debugInfoEnabled(false);
});
this will remove class ng-scope
ng-binding
on the html markup
restrict DI mode
<html ng-app="app" ng-strict-di>
...
...
when use ng-strict-di mode, every service or controller must be use []
syntax or $inject syntax to inject dependence, otherwise, it will have error
ng-model-options
the model vm.test
will be updated as long as the cusor blur
<input type="text" id="xxx" ng-model="vm.test" ng-model-options = "{updateOn:'blur'}"/>
<input type="text" id="xxx" ng-model="vm.test" ng-model-options = "{debounce: 1500}"/>
debounce can be object, which means, it is default to 500, and once it blur, the debounce is 0
<input type="text" id="xxx" ng-model="vm.test" ng-model-options = "{debounce: {'default':500, 'blur':0}}"/>
roll back changes
this only works on the field that as ng-model-options bindings $rollbackViewValue()
vm.cancelEntry = function(control, event) {
if(event.keyCode === 27) {
control.$rollbackViewValue();
}
}
<input type="text"
id="xxx"
ng-model="vm.test"
ng-model-options = "{updateOn:'blur'}"
ng-keyup="vm.cancelEntry(classForm.xxx, $event)"/>
rollback can also proform on from level, this will reset the entire form
<form class="form" name="classForm" ng-submit="vm.submit()" ng-model-options="{updateOn:'submit'}" novalidate>
<button ng-click="classForm.$rollbackViewValue()"> Reset </button>
submission detection
this can be used to detect if form has been submitted
<div ng-if="classForm.$submitted">
Data was submitted
</div>
binding to a getter/setter function
use the getterSetter model option to bind to a getter/setter function
use at the form level to bind to getter/setter functions for all input elements
ng-model-options=”{ getterSetter: true }”
vm.class.dates = {
startDate: function(value) {
if(angular.isDefined(value)) {
_startDate = value;
vm.class.startDate=_startDate;
}
return _startDate;
}
}
<input type="text"
id="xxx"
ng-model="vm.class.dates.startDate"
ng-model-options = "{ getterSetter: true }"/>
validator
<div class="form-group"
ng-class="{'has-error':classForm.inputClassName.$invalid && classForm.inputClassName.$dirty}">
</div>
ng-messages
ng-messages-multiple // this will display all error messages that matches
ng-message directive
ng-messages-include
<span class="help-block has-error"
ng-if="classForm.inputInstructorEmail.$dirty"
ng-messages="classForm.inputInstructorEmail.$error"
ng-messages-include="app/errorMessages.html"
ng-messages-multiple>
<span ng-message="minlength">
overwrite minlength validate message
</span>
</span>
custom validator
function dateRangeValidator() {
return {
restrict: 'A',
require: 'ngModel',
scope: {
beginDate: '=dateRangeValidator'
},
link: function(scope, element, attrs, ngModel) {
ngModel.$validators.dateRange = function(modelValue) {
return Date.parse(modelValue) >= Date.parse(scope.beginDate);
};
scope.$watch('beginDate', function() {
ngModel.$validate();
});
}
}
}
<input date-range-validator="vm.class.startDate" .. />
asynchronous validation
$asyncValidator
angular.module('common.directives')
.directive('duplicateClassnameValidator', ['$q', 'classResource', duplicateClassNameValidator]); //classResource is a backend service
function duplicateClassNameValidator($q, classResource) {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
var classId = attrs.duplicateClassNameValidator;
ngModel.$asyncValidators.duplicateClassName = function(modelValue) {
var defer = $q.defer();
classResource.get({classId: classId, className: modelValue},
function(response) { defer.reject('exists');},
function(response) {defer.resolve();});
return defer.promise();
}
}
};
}
// if the asyncValidator is not fullfilled, the status of the input is $pending, that can be used to show spin
image
<span ng-if="classForm.inputClassName.$pending">
... Verifying Unique Name
</span>
html5 mode routing
in angular 1.3, to enable html5 model, we must add base
tag in the head tag
update router params in controller
$scope.updateRouter = function() {
$route.updateParams({classIdx: $scope.classIdx});
}
prevent router change
$rootScope.$on('$routeChangeStart', function(event, next, current) {
if(!!current $$ current.id === 'classes' && current.scope.unsavedChanges) {
event.preventDefault();
}
});
$scope.startEditing = function() {
$scope.unsavedChanges = true;
}
$scope.save = function() {
$scope.unsavedChanges = false;
}
$scope.$watchGroup
this is very useful for some case you want to watch two fields on the form, and either fields will trigger the listener
$scope.$watchGroup(['propert1', 'propert2'], function(newVals, oldVals) {
for(var i = 0; i < newVals.length; i++) {
if(newVals[i] !== oldVals[i]) {
alert('value changed');
}
}
})
$routerProvider.caseInsensitiveMatch = true;
$anchorScroll Service
$location.hash('3'), this will scroll to the element which id is 3
$anchorScroll.yOffset = 10;
$anchorScorll(); //scroll back to the place that match the url
ES6 Promise
var promise = $q(function(resolve, reject) {
resolve(...)
})
new filters
//this will show only 4 charactors of studentId
// this will show $99.9
ng-true-value
this is useful for checkbox
when the value of registered is yes or no
<input type="checkbox" ng-true-value="'yes'" ng-false-value="'no'" ng-model="student.registered">
directive controllerAs
...
return {
scope: ...
templateUrl: '',
controllerAs: 'ctrl',
bindToController: true, //this will bind the property on of scope to ctrl
controller: function() {
this.selected = false;
this.toggleSelect = function() {
...
}
}
}
$includeContentRequested event
$scope.$on('$includeContentRequested', function(e, nameOfTemplate) {
});
$scope.$on('$includeContentLoaded', function(e, nameOfTemplate) {
});
$scope.$on('$includeContentError', function(e, nameOfTemplate) {
});
<div ng-include="'navBar.html'"></div>
these event will be trigged when ng-include
used
blog comments powered by Disqus