Last active
February 19, 2016 14:29
-
-
Save vardius/e7f5d55c21f846577bba to your computer and use it in GitHub Desktop.
ES6 Angular OO Aproach
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* (c) Rafał Lorenz <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
'use strict'; | |
//Location in the `filters` directory | |
//This way `Loader class will find it. | |
export default function checkmark() { | |
return function(input) { | |
return input ? '\u2713' : '\u2718'; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* (c) Rafał Lorenz <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
'use strict'; | |
//Location in the `constants` directory | |
//This way `Loader class will find it. | |
export default class Settings { | |
constructor() { | |
this.url = ""; | |
this.clientId = ''; | |
this.clientSecret = ''; | |
this.port = "80"; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* (c) Rafał Lorenz <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
'use strict'; | |
//Location in the `directives` directory | |
//This way `Loader class will find it. | |
class MyDirective { | |
constructor($interval) { | |
'ngInject'; | |
this.template = '<div>I\'m a directive!</div>'; | |
this.restrict = 'E'; | |
this.scope = {}; | |
this.$interval = $interval; | |
} | |
compile(tElement) { | |
tElement.css('position', 'absolute'); | |
} | |
link(scope, element) { | |
this.$interval(() => this.move(element), 1000); | |
} | |
move(element) { | |
element.css('left', (Math.random() * 500) + 'px'); | |
element.css('top', (Math.random() * 500) + 'px'); | |
} | |
} | |
MyDirective.$inject = ['$interval']; | |
export default MyDirective; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* (c) Rafał Lorenz <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
'use strict'; | |
//Location in the `factories` directory | |
//This way `Loader class will find it. | |
export default class ThingFactory { | |
constructor($timeout) { | |
this.$timeout = $timeout; | |
} | |
newThing() { | |
console.log('Getting a new Thing...'); | |
return this.$timeout(() => new Thing(), 1000); | |
} | |
} | |
ThingFactory.$inject = ['$timeout']; | |
export default ThingFactory; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/**(c) Rafał Lorenz <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
'use strict'; | |
//Location in the `factories` directory | |
//This way `Loader class will find it. | |
export default class Model { | |
constructor($resource, url) { | |
this.$resource = $resource; | |
this.url = url; | |
this.resource = this.getResource(); | |
} | |
getAll(params) { | |
let model = this.resource.query((typeof params === 'undefined' ? {} : params)); | |
return this.returnPromise(model); | |
} | |
getById(id) { | |
let model = this.resource.get({id: id}); | |
return this.returnPromise(model); | |
} | |
create(data) { | |
let model = new this.resource(data); | |
return model.$save(); | |
} | |
update(id, data) { | |
data.id = id; | |
var model = new this.resource(data); | |
return model.$update(); | |
} | |
remove(id) { | |
var data = {id: id}; | |
var model = new this.resource(data); | |
return model.$delete(); | |
} | |
getResource() { | |
return this.$resource(this.url, {id: '@id'}, { | |
'update': { | |
method: 'PUT' | |
}, | |
'get': { | |
method: 'GET' | |
}, | |
'save': { | |
method: 'POST' | |
}, | |
'query': { | |
method: 'GET' | |
}, | |
'remove': { | |
method: 'DELETE' | |
}, | |
'delete': { | |
method: 'DELETE' | |
} | |
}); | |
} | |
static returnPromise(object) { | |
return object.$promise.then(function (result) { | |
return result; | |
}); | |
} | |
/** | |
* Important method! | |
* When class located inside `factories` directory contains this method, | |
* will be registered as service module but WORKS AS FACTORY. | |
* This is more correct way to register factories! | |
* | |
* @param $resource | |
* @param Settings | |
* @returns {Function} | |
*/ | |
static factory($resource) { | |
'ngInject'; | |
return (url) => { | |
return new Model($resource, url); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* (c) Rafał Lorenz <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
'use strict'; | |
//Location in the `components` directory | |
//This way `Loader class will find it. | |
export default class navHeader { | |
constructor() { | |
this.templateUrl = 'components/header.html'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* (c) Rafał Lorenz <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
'use strict'; | |
//Location in the `controllers` directory | |
//This way `Loader class will find it. | |
export default class HomeController { | |
constructor() { | |
this.title = 'Home Controller'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* (c) Rafał Lorenz <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
'use strict'; | |
export default class Loader { | |
/** | |
* Loader controller | |
* | |
* Requires `app` as string application name. | |
* Allows to provide custom structure map. | |
* | |
* @param app | |
* @param structure | |
*/ | |
constructor(app, structure) { | |
const bulk = require('bulk-require'); | |
this.module = angular.module(app); | |
this.structure = structure || { | |
constant: bulk(__dirname, ['./constants/**/!(*.spec).js']), | |
config: bulk(__dirname, ['./config/**/!(*.spec).js']), | |
controller: bulk(__dirname, ['./controllers/**/!(*.spec).js']), | |
service: bulk(__dirname, ['./services/**/!(*.spec).js']), | |
provider: bulk(__dirname, ['./providers/**/!(*.spec).js']), | |
factory: bulk(__dirname, ['./factories/**/!(*.spec).js']), | |
component: bulk(__dirname, ['./components/**/!(*.spec).js']), | |
directive: bulk(__dirname, ['./directives/**/!(*.spec).js']), | |
filter: bulk(__dirname, ['./filters/**/!(*.spec).js']) | |
}; | |
Object.defineProperty(Function.prototype, 'name', { | |
get: function () { | |
return /function ([^(]*)/.exec(this + "")[1]; | |
} | |
}); | |
this.register(); | |
} | |
/** | |
* Register app modules from structure map | |
*/ | |
register() { | |
let self = this; | |
angular.forEach(self.structure, function (value, key) { | |
self.declare(key, value); | |
}); | |
} | |
/** | |
* Register app modules by structure key | |
* | |
* @param name | |
* @param map | |
*/ | |
declare(name, map) { | |
let self = this; | |
Object.keys(map).forEach((key) => { | |
let item = map[key]; | |
if (!item) { | |
return; | |
} | |
if (item && typeof item === 'function') { | |
self[name](item); | |
} else { | |
self.declare(name, item); | |
} | |
}); | |
} | |
/** | |
* Register constants | |
* | |
* @param item | |
* @returns {Loader} | |
*/ | |
constant(item) { | |
let constructorFn = this.normalizeConstructor(item); | |
this.module.constant(constructorFn.name, new constructorFn()); | |
return this; | |
} | |
/** | |
* Add config | |
* | |
* @param item | |
* @returns {Loader} | |
*/ | |
config(item) { | |
let constructorFn = this.normalizeConstructor(item); | |
this.module.config(constructorFn); | |
return this; | |
} | |
/** | |
* Register controller | |
* | |
* @param item | |
* @returns {Loader} | |
*/ | |
controller(item) { | |
let constructorFn = this.normalizeConstructor(item); | |
this.module.controller(constructorFn.name, constructorFn); | |
return this; | |
} | |
/** | |
* Register component | |
* | |
* @param item | |
* @returns {Loader} | |
*/ | |
component(item) { | |
let constructorFn = this.normalizeConstructor(item); | |
this.module.component(constructorFn.name, new constructorFn()); | |
return this; | |
} | |
/** | |
* Register service | |
* | |
* @param item | |
* @returns {Loader} | |
*/ | |
service(item) { | |
let constructorFn = this.normalizeConstructor(item); | |
this.module.service(constructorFn.name, constructorFn); | |
return this; | |
} | |
/** | |
* Register provider | |
* @param item | |
* @returns {Loader} | |
*/ | |
provider(item) { | |
let constructorFn = this.normalizeConstructor(item); | |
this.module.provider(constructorFn.name, constructorFn); | |
return this; | |
} | |
/** | |
* Register factory | |
* | |
* There are two possible way to implement factories. | |
* `module.factory()` method is specifically for when you are not using classes. | |
* The `module.service()` method was specifically designed for when you want to define your services as classes (or instantiable types). | |
* So there is actually no point in trying to hack together a way to register a class via the `module.factory()` method. | |
* Just use `module.service()` instead. | |
* | |
* @param item | |
* @returns {Loader} | |
*/ | |
factory(item) { | |
let constructorFn = this.normalizeConstructor(item); | |
if (constructorFn.factory) { | |
this.module.service(constructorFn.name, constructorFn.factory); | |
} else { | |
this.module.factory(constructorFn.name, this.createFactoryArray(constructorFn)); | |
} | |
return this; | |
} | |
/** | |
* Register directive | |
* | |
* @param item | |
* @returns {Loader} | |
*/ | |
directive(item) { | |
let constructorFn = this.normalizeConstructor(item); | |
if (!constructorFn.prototype.compile) { | |
constructorFn.prototype.compile = () => { | |
}; | |
} | |
let originalCompileFn = this.cloneFunction(constructorFn.prototype.compile); | |
this.override(constructorFn.prototype, 'compile', function () { | |
return function () { | |
originalCompileFn.apply(this, arguments); | |
if (constructorFn.prototype.link) { | |
return constructorFn.prototype.link.bind(this); | |
} | |
}; | |
}); | |
this.module.directive(constructorFn.name, this.createFactoryArray(constructorFn)); | |
return this; | |
} | |
/** | |
* Register filter | |
* | |
* @param item | |
* @returns {Loader} | |
*/ | |
filter(item) { | |
let constructorFn = this.normalizeConstructor(item); | |
this.module.filter(constructorFn.name, constructorFn); | |
return this; | |
} | |
/** | |
* Clone a function | |
* @param original | |
* @returns {Function} | |
*/ | |
cloneFunction(original) { | |
return function () { | |
return original.apply(this, arguments); | |
}; | |
} | |
/** | |
* Convert a constructor function into a factory function which returns a new instance of that | |
* constructor, with the correct dependencies automatically injected as arguments. | |
* | |
* In order to inject the dependencies, they must be attached to the constructor function with the | |
* `$inject` property annotation. | |
* | |
* @param constructorFn | |
* @returns {Array.<T>} | |
* @private | |
*/ | |
createFactoryArray(constructorFn) { | |
var args = constructorFn.$inject || []; | |
var factoryArray = args.slice(); | |
factoryArray.push((...args) => { | |
var instance = new constructorFn(...args); | |
for (var key in instance) { | |
if (instance.hasOwnProperty(key)) { | |
instance[key] = instance[key]; | |
} | |
} | |
return instance; | |
}); | |
return factoryArray; | |
} | |
/** | |
* If the constructorFn is an array of type ['dep1', 'dep2', ..., constructor() {}] | |
* we need to pull out the array of dependencies and add it as an $inject property of the | |
* actual constructor function. | |
* | |
* @param input | |
* @returns {*} | |
* @private | |
*/ | |
normalizeConstructor(input) { | |
var constructorFn; | |
if (input.constructor === Array) { | |
var injected = input.slice(0, input.length - 1); | |
constructorFn = input[input.length - 1]; | |
constructorFn.$inject = injected; | |
} else { | |
constructorFn = input; | |
} | |
return constructorFn; | |
} | |
/** | |
* Override an object's method with a new one specified by `callback`. | |
* | |
* @param object | |
* @param methodName | |
* @param callback | |
*/ | |
override(object, methodName, callback) { | |
object[methodName] = callback(object[methodName]) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* (c) Rafał Lorenz <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
'use strict'; | |
import angular from 'angular'; | |
import loader from './loader'; | |
import 'angular-ui-router'; | |
const app = 'app'; | |
const requires = [ | |
'ui.router', | |
]; | |
window.app = angular.module(app, requires); | |
const register = new loader(app); | |
angular.bootstrap(document, [app], { | |
strictDi: true | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* (c) Rafał Lorenz <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
'use strict'; | |
//Location in the `config` directory | |
//This way `Loader class will find it. | |
export default function routerConfig($stateProvider, $locationProvider, $urlRouterProvider) { | |
'ngInject'; | |
$urlRouterProvider.otherwise('/'); | |
$locationProvider.html5Mode(true); | |
$stateProvider | |
.state('Home', { | |
url: '/', | |
controller: 'HomeController as home', | |
templateUrl: 'home.html', | |
title: 'Home' | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* (c) Rafał Lorenz <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
'use strict'; | |
//Location in the `providers` directory | |
//This way `Loader class will find it. | |
export default class ThingProvider { | |
constructor() { | |
this.settings = { | |
storage: 'sessionStorage', //localStorage | |
storageKey: 'linkedInConfig' | |
}; | |
} | |
config(settings) { | |
for (var attr in settings) { | |
if (settings.hasOwnProperty(attr)) { | |
this.settings[attr] = settings[attr]; | |
} | |
} | |
let state = this.getState(); | |
if (!state) { | |
this.setState(this.settings.state) | |
} else { | |
this.settings.state = state; | |
} | |
} | |
setState(data) { | |
window[this.settings.storage].setItem(this.settings.storageKey + '-state', JSON.stringify(data)); | |
} | |
getState() { | |
var data = window[this.settings.storage].getItem(this.settings.storageKey + '-state'); | |
return (data) ? JSON.parse(data) : false; | |
} | |
$get() { | |
return { | |
getState: this.getState.bind(this) | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* (c) Rafał Lorenz <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
'use strict'; | |
export default class UserService { | |
constructor($http) { | |
'ngInject'; | |
this.$http = $http; | |
} | |
getFullName() { | |
return this.$http.get('api/user/details'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment