var app = ... functionappConfig($stateProvider, $urlRouterProvider) { // use any parameter names, no DI here $urlRouterProvider.otherwise('/issues'); } app.config(['$stateProvider, $urlRouterProvider', appConfig]);
When writing AngularJs, dynamic dependency injection is everywhere: in controller
functions, modules, filters. While injecting into controller function is obvious,
it is unclear how to inject dependencies into link or filter functions.
You can do the injection in these cases like this:
// directive and controller angular.module('MyApp', []) .directive(['$scope', 'MyDependency', function ($scope, MyDependency) { // injected variables to be used inside link function return { restrict: 'E', scope: true, templateUrl: 'study-line-chart/study-line-chart.tpl.html', controller: ['$scope', 'utils', function ($scope, utils) { // separate injection if necessary for controller }], link: function (scope, element, attrs) { // scope === $scope and MyDependency injected variables } }; }]) .filter('formattedName', ['MyUtils', function (myUtils) { // myUtils is injected into filter returnfunction (name) { return myUtils.formatName(name); }; }]);
Angularjs allows overriding modules at any time. Good for testing, awful
for working as a team. I wrote stop-angular-overrides
script that throws an Error on any override attempt. More examples
in this blog post.
We gave form and input fields names that are valid JavaScript identifiers.
This gives us an advantage when we query the state of the form from the browser console
1 2 3 4 5 6 7 8 9 10 11 12 13
// grab element's angular wrapper var el = angular.element('form[name="myForm"]'); var scope = el.scope(); // get the form structure, automatically created by angular var form = scope.myForm; // has user touched start day input? form.start_date.$pristine; // has user entered something in start date? form.start_date.$dirty; // is start date input valid? form.start_date.$valid; // which validation fails for start_date input? form.start_date.$error
Because form data is placed in the scope, we can watch it just as any other scope
expression
1 2 3
$scope.$watch('myForm.start_date.$dirty', function (newStartDate) { ... });
Finally, the entire form has $valid, $dirty, etc properties on the scope that you can use to enable / disable
the submit button. The angular form automatically computes these properties from the children inputs.
Using Angular services outside Angular application
You do not need to run the entire Angular application to use separate services. For example
if you need just promises, you can inject $q service and use it in your non-Angular code.
1 2 3 4 5 6 7
functionasyncFoo() { var $q = angular.injector(['ng']).get('$q'); return $q.when('foo'); } asyncFoo().then(function (value) { // value is 'foo' });
Defaults object with Angular
Often we need to combine options object passed into a function with defaults
object. If there is the same propety in both objects, the options object should overwrite
the defaults. This can be done using a composition of two angular built-in functions
1 2 3 4 5 6 7 8 9 10 11 12
functiondefaults(_defaults, opts) { opts = opts || {}; return angular.extend(angular.copy(_defaults), opts); } functionfoo(options) { var _defaults = { bar: 'baz' }; options = defaults(_defaults, options); } foo({ bar: 'my bar' }); // options is { bar: 'my bar' } foo(); // options is { bar: 'baz' }