Code samples at:
Software Engineer at
building applications with
We're Hiring
invoke(fn)
Invoke the method and supply the method arguments from the $injector.
instantiate(Type)
Create a new instance of JS type. The method takes a constructor function, invokes the new operator, and supplies all of the arguments to the constructor function as specified by the constructor annotation.
Write a factory
Use a Factory to define a type that will be called with new
Use a Service to create an object that will be shared across all modules and components (singleton)
Write a service
Write a provider
"use the source" + luke;
What is really going on here?
var providerCache = {};
function provider(name, provider_) {
if (isFunction(provider_) || isArray(provider_)) {
provider_ = providerInjector.instantiate(provider_);
}
if (!provider_.$get) {
throw "Provider '" + name + "' must define $get factory method.", name);
}
return providerCache[name + providerSuffix] = provider_;
}
function factory(name, factoryFn) {
return provider(name, {
$get: factoryFn
});
}
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}
Latest Angular Source
$get
Write a useful provider
angular.module('ngRoute', []).
provider('$route', [function () {
var routeCache = {};
return {
when: function (url_template, options) {
routeCache[url_template] = options;
},
$get: ['...', function (...) { ... }
};
}]);
angular.module('myModule', ['ngRoute']).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/my-route/:some_param', {
controller: 'myController as my_controller',
templateUrl: 'my_template.html',
resolve: {
dependency: ['$route', function ($route) {...}]
}
});
}]);
Problem:
Requirements:
angular.module('spacelist').
config(['webServiceKeysProvider', function (webServiceKeysProvider) {
webServiceKeysProvider.
setGoogleAnalyticsKey('<%= GA_KEY =>').
setKissmetricsId('<%= KM_ID =>').
setGoogleMapsKey('<%= GMAPS_KEY =>').
setStripePublicKey('<%= STRIPE_PUB_KEY =>');
}]).
config(['userManagerProvider', function (userManagerProvider) {
userManagerProvider.inject_current_user(<%= current_user.as_json() =>);
}]).
config(['appManagerProvider', function (appManagerProvider) {
appManagerProvider.inject_app_data(<%= app_data.to_json() %>);
}]);
angular.module('webServices')
.service('googleMapsLoader', [
'$window', 'ScriptInjector', 'webServiceKeys', function
($window, ScriptInjector, webServiceKeys) {
var maps_callback_name = 'google_maps_ready';
this.load = function (callback) {
if (typeof $window.google === 'object') {
callback($window.google);
} else {
$window[maps_callback_name] = function () {
callback($window.google);
}
new ScriptInjector(
'//maps.googleapis.com/maps/api/js?v=3.18' +
'&key=' + webServiceKeys.getGoogleMapsKey() +
'&callback=' + maps_callback_name).
inject();
}
};
}]);
Problem:
Requirements:
modalProvider.add('loginSignup', {
controller: 'LoginSignupController as login_signup_ctrl',
templateUrl: 'angular-app/auth/login_signup.html',
});
...
modalProvider.add('purchaseBCA', {
controller: 'BCAPurchaseController as bca_purchase_ctrl',
templateUrl: 'angular-app/bca/modals/bca_purchase.html',
});
modal.show('loginSignup', next: '/privileged_url/');
...
modal.show('purchaseBCA', {property: property, bca: bca});
"use strict";
angular.module('spacelist.core').
provider('modal', [function () {
var modalProvider = {},
modals = {};
modalProvider.add = function (name, options) {
modals[name] = _.extend({
preventClose: false,
locals: {},
}, options);
return this;
};
modalProvider.$get = [...];
return modalProvider;
}]);
[..., function ($rootScope, $controller, $compile, $window, loadTemplate) {
return {
show: function (name, locals) {
var modal_options = modals[name],
modal_element = angular.element(
'<div class="modal modal-show">' +
'<div class="modal-wrapper"><div class="modal-content"></div></div>' +
'<div class="modal-cover"></div></div>'),
content_element = modal_element.find('.modal-content'),
modalController = {
show: function () { angular.element('body').append(modal_element); },
close: function () { modal_element.remove(); }
},
controller_locals = angular.extend({}, modal_options.locals, locals, {
$scope: $rootScope.$new(true),
modalController: modalController
});
$controller(modal_options.controller, controller_locals);
content_element.html(loadTemplate(modal_options.templateUrl));
var link = $compile(content_element.contents());
link(controller_locals.$scope);
modalController.show();
return modalController;
}};
}}];
var cover_element = modal_element.find('.modal-cover')
if (!modal_options.preventClose) {
cover_element.on('click', modalController.close);
$window.addEventListener('keydown', escHandler);
}
function escHandler(event) {
if (event.keyCode === 27) {
modalController.close();
$window.removeEventListener('keydown', escHandler);
}
}
Problem:
Requirements
angular.module('spacelist.profile', ['spacelist.conversations'])
.config([
'conversableTypeProvider', function
(conversableTypeProvider) {
conversableTypeProvider.register('Profile', {
controller: 'profileController as profile_ctrl',
templateUrl: 'angular-app/profile/profile_conversable.html',
resolve: {
user: ['params', 'User', function (params, User) {
return User.query({profile_id: params.conversable_id}).
$promise.then(function (users) {
if (users.length === 0) {
throw "Unknown user";
}
return users[0];
});
}]
},
});
}]);
<conversable
conversable-type="conversable.type"
conversable-id="conversable.id">
</conversable>
angular.module('spacelist.conversations').
directive('conversable', [
'$compile', '$controller', 'conversableType', function
($compile, $controller, conversableType) {
return {
scope: {
type: '=conversableType',
id: '=conversableId'
},
link: function (scope, element) {
scope.$watch('type + id', function () {
if (scope.type && scope.id) {
build_element();
} else {
element.empty();
}
});
}
function build_element() { ... }
};
}]);
function build_element() {
var conversable_component =
conversableType.getComponent(scope.type),
child_scope = scope.$new(true);
element.addClass('loading');
element.empty();
conversable_component.resolveLocalsFor(scope.id).
then(function (locals) {
var controller = conversable_component.getController();
element.html(locals.template);
var link = $compile(element.contents());
locals.$scope = child_scope;
$controller(controller, locals);
link(child_scope);
}).
catch(show_error).
finally(element.removeClass.bind(element, 'loading'));
}
Â
Tyler Jones <tyler@squirly.ca>
GitHub: @squirly
Is Hiring!