Last active
December 18, 2015 17:59
-
-
Save x1ddos/5822385 to your computer and use it in GitHub Desktop.
AngularJS 1.1.5 + Google Closure Library (just a little) + Closure Compiler (obviously) experiment
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
<html ng-app="ng-demo-app"> | |
<head> | |
<title>AngularJS simple app demo</title> | |
</head> | |
<body ng-controller="MainCtrl"> | |
<input type="text" ng-model="name" ng-required> | |
<div>{{name}}</div> | |
<div ng-controller="ChildCtrl"> | |
<input type="text" ng-model="salut"> | |
<div>{{salutation}}</div> | |
</div> | |
<p current-time="{{timeFormat}}"></p> | |
<p>format: | |
<select ng-model="timeFormat" ng-options="o for o in timeOpts"></select> | |
</p> | |
<script src="/angular.min.js"></script> | |
<script src="ng-demo-app.min.js"></script> | |
</body> | |
</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
(function(){ 'use strict';function b(a) { | |
a && (this.a = a, this.a.name = "alex") | |
} | |
b.$inject = ["$scope"]; | |
b.prototype.getName = function() { | |
return(this.a.name || "anonymous")[0].toUpperCase() + (this.a.name || "anonymous").slice(1) | |
}; | |
function c(a) { | |
b.call(this); | |
this.d = this.d.bind(this); | |
a && (this.a = a, a = function() { | |
return[this.a.name, this.a.salut] | |
}.bind(this), this.a.$watch(a, this.d, !0)) | |
} | |
(function() { | |
function a() { | |
} | |
a.prototype = b.prototype; | |
c.l = b.prototype; | |
c.prototype = new a | |
})(); | |
c.$inject = ["$scope"]; | |
c.prototype.d = function() { | |
this.a.salutation = (this.a.salut || "hello")[0].toUpperCase() + (this.a.salut || "hello").slice(1) + ", " + this.getName() + "!" | |
}; | |
function d(a, e) { | |
this.$timeout = a; | |
this.i = e; | |
this.timeFormat = "medium"; | |
this.link = this.link.bind(this); | |
this.b = this.b.bind(this); | |
this.e = this.e.bind(this) | |
} | |
d.prototype.c = "currentTime"; | |
d.prototype.h = "medium short fullDate longDate mediumDate shortDate mediumTime shortTime".split(" "); | |
d.prototype.f = "medium"; | |
function f(a, e) { | |
return{link:(new d(a, e)).link} | |
} | |
f.$inject = ["$timeout", "dateFilter"]; | |
d.prototype.link = function(a, e, h) { | |
this.scope = a; | |
this.j = e; | |
this.g = h; | |
this.g.$observe(this.c, this.e); | |
this.b() | |
}; | |
d.prototype.e = function() { | |
this.timeFormat = this.g[this.c] || this.f; | |
this.b() | |
}; | |
d.prototype.b = function() { | |
this.$timeout.cancel(this.k); | |
var a = this.i(new Date, this.timeFormat); | |
this.j.html("Local time: " + a); | |
this.k = this.$timeout(this.b, 1E3) | |
}; | |
function g(a) { | |
a.timeOpts = d.prototype.h; | |
a.timeFormat = d.prototype.f | |
} | |
g.$inject = ["$rootScope"]; | |
angular.module("ng-demo-app", []).controller("MainCtrl", b).controller("ChildCtrl", c).directive(d.prototype.c, f).run(g); | |
}).call(window) |
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
// Compile with: | |
// | |
// java -jar $COMPILER_JAR \ | |
// --define=goog.DEBUG=false \ | |
// --warning_level=VERBOSE \ | |
// --summary_detail_level=3 \ | |
// --compilation_level=ADVANCED_OPTIMIZATIONS \ | |
// --language_in ECMASCRIPT5_STRICT --angular_pass --formatting PRETTY_PRINT \ | |
// --externs ~/src/closure/compiler/contrib/externs/angular.js \ | |
// --js $CLOSURE_LIB/closure/goog/base.js \ | |
// --js ng-demo-app.src.js --output_wrapper '(function(){ %output% }).call(window)' \ | |
// > ng-demo-app.min.js | |
/** | |
* @fileoverview AngularJS simple app demo | |
*/ | |
goog.provide('demos.ng.simple.MainCtrl'); | |
goog.provide('demos.ng.simple.ChildCtrl'); | |
/** | |
* Main controller | |
* @param {angular.Scope=} $scope | |
* @constructor | |
* @ngInject | |
*/ | |
demos.ng.simple.MainCtrl = function($scope) { | |
if ($scope) { | |
this.$scope = $scope; | |
/** | |
* @type {string} | |
* @expose | |
*/ | |
this.$scope.name = 'alex'; | |
} | |
} | |
demos.ng.simple.MainCtrl.prototype.getName = function() { | |
return titleize(this.$scope.name || 'anonymous'); | |
} | |
/** | |
* Child controller | |
* @param {angular.Scope=} $scope | |
* @constructor | |
* @extends {demos.ng.simple.MainCtrl} | |
* @ngInject | |
*/ | |
demos.ng.simple.ChildCtrl = function($scope) { | |
goog.base(this); | |
this.onScopeChange = this.onScopeChange.bind(this); | |
/** | |
* @type {string} | |
* @expose | |
*/ | |
this.$scope.salut; | |
/** | |
* @type {string} | |
* @expose | |
*/ | |
this.$scope.salutation; | |
if ($scope) { | |
this.$scope = $scope; | |
var watcher = (function(){ | |
return [this.$scope.name, this.$scope.salut] | |
}).bind(this); | |
this.$scope.$watch(watcher, this.onScopeChange, true); | |
} | |
} | |
goog.inherits(demos.ng.simple.ChildCtrl, demos.ng.simple.MainCtrl); | |
/** | |
* Callback for when name or salut scope values change. | |
* Updates salutation scope value. | |
*/ | |
demos.ng.simple.ChildCtrl.prototype.onScopeChange = function() { | |
this.$scope.salutation = this.getSalutation(); | |
} | |
/** | |
* Returns a "hello, name" salutation using name and salut from the scope. | |
*/ | |
demos.ng.simple.ChildCtrl.prototype.getSalutation = function() { | |
var salut = this.$scope.salut || 'hello'; | |
return titleize(salut) + ', ' + this.getName() + '!'; | |
} | |
/** | |
* A directive that displays current local time. | |
* @constructor | |
*/ | |
demos.ng.simple.TimeDirective = function($timeout, dateFilter) { | |
this.$timeout = $timeout; | |
this.dateFilter = dateFilter; | |
/** @type {string} */ | |
this.timeFormat = 'medium'; | |
/** @type {angular.$q.Promise} */ | |
this.timerPromise; | |
this.link = this.link.bind(this); | |
this.updateTime = this.updateTime.bind(this); | |
this.onTimeFormatChange = this.onTimeFormatChange.bind(this); | |
/** @type {angular.Scope} */ | |
this.scope; | |
/** @type {angular.JQLite} */ | |
this.elem; | |
/** @type {angular.Attributes} */ | |
this.attrs; | |
} | |
/** @const */ | |
demos.ng.simple.TimeDirective.prototype.DIR_NAME = 'currentTime'; | |
/** @const */ | |
demos.ng.simple.TimeDirective.prototype.TIME_OPTS = [ | |
'medium', 'short', 'fullDate', 'longDate', 'mediumDate', 'shortDate', | |
'mediumTime', 'shortTime' | |
] | |
/** @const */ | |
demos.ng.simple.TimeDirective.prototype.DEFAULT_TIME_FORMAT = 'medium'; | |
/** | |
* TimeDirective factory. | |
* @return {Object} | |
* @ngInject | |
*/ | |
demos.ng.simple.TimeDirective.factory = function($timeout, dateFilter) { | |
var dir = new demos.ng.simple.TimeDirective($timeout, dateFilter); | |
return { | |
link: dir.link | |
} | |
} | |
/** | |
* Linking function. | |
* @param {angular.Scope} scope | |
* @param {angular.JQLite} elem | |
* @param {angular.Attributes} attrs | |
*/ | |
demos.ng.simple.TimeDirective.prototype.link = function(scope, elem, attrs) { | |
this.scope = scope; | |
this.elem = elem; | |
this.attrs = attrs; | |
this.attrs.$observe(this.DIR_NAME, this.onTimeFormatChange); | |
this.updateTime(); | |
} | |
/** | |
* Watcher callback for when a user selects a new time format. | |
* @param {*} val | |
*/ | |
demos.ng.simple.TimeDirective.prototype.onTimeFormatChange = function(val) { | |
this.timeFormat = this.attrs[this.DIR_NAME] || this.DEFAULT_TIME_FORMAT; | |
this.updateTime(); | |
} | |
/** | |
* Updates element with the current time each second. | |
*/ | |
demos.ng.simple.TimeDirective.prototype.updateTime = function() { | |
this.$timeout.cancel(this.timerPromise); | |
var now = new Date(); | |
var formatted = this.dateFilter(now, this.timeFormat); | |
this.elem.html('Local time: ' + formatted); | |
this.timerPromise = this.$timeout(this.updateTime, 1000); | |
} | |
// ---------------------------------------------------------------------------- | |
// the app | |
/** | |
* Runs only once at startup time | |
* @param {angular.Scope} $rootScope | |
* @ngInject | |
*/ | |
function onAppStartup($rootScope) { | |
/** | |
* Time format options for select box | |
* @type {Array.<string>} | |
* @expose | |
*/ | |
$rootScope.timeOpts = | |
demos.ng.simple.TimeDirective.prototype.TIME_OPTS; | |
/** | |
* @type {string} | |
* @expose | |
*/ | |
$rootScope.timeFormat = | |
demos.ng.simple.TimeDirective.prototype.DEFAULT_TIME_FORMAT; | |
} | |
/** @type {angular.Module} */ | |
var app = angular.module('ng-demo-app', []). | |
controller('MainCtrl', demos.ng.simple.MainCtrl). | |
controller('ChildCtrl', demos.ng.simple.ChildCtrl). | |
directive(demos.ng.simple.TimeDirective.prototype.DIR_NAME, | |
demos.ng.simple.TimeDirective.factory). | |
run(onAppStartup); | |
// ---------------------------------------------------------------------------- | |
// utils | |
/** | |
* Changes first letter to the upper case | |
* @param {string} str | |
* @return {string} | |
*/ | |
function titleize(str) { | |
if (!str) return str; | |
return str[0].toUpperCase() + str.slice(1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the code snippet. I think this approach increase the maintainability and testability. We only have one problem: If we use a directive multiple times on a site. Directive.factory will only be called once. So all directives on sites share the same Directive object. Do you have an idea whats going wrong here?