Created
July 8, 2015 15:31
An Experiment In What React's JSX Might Feel Like In AngularJS
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
<!doctype html> | |
<html ng-app="Demo"> | |
<head> | |
<meta charset="utf-8" /> | |
<title> | |
An Experiment In What React's JSX Might Feel Like In AngularJS | |
</title> | |
<link rel="stylesheet" type="text/css" href="./demo.css"></link> | |
</head> | |
<body> | |
<h1> | |
An Experiment In What React's JSX Might Feel Like In AngularJS | |
</h1> | |
<div bn:hello-world> | |
Woot! | |
</div> | |
<!-- | |
Load scripts. | |
-- | |
NOTE: Our main script block isn't a JavaScript block - it's a "text/ngx" block. | |
The ngx.js file will defer the bootstrapping of the AngularJS application until | |
the ngx content has been parsed and re-injected into the Head as valid JavaScript. | |
--> | |
<script type="text/javascript" src="../../vendor/jquery/jquery-2.1.0.min.js"></script> | |
<script type="text/javascript" src="../../vendor/angularjs/angular-1.3.16.min.js"></script> | |
<script type="text/javascript" src="./ngx.js"></script> | |
<script type="text/ngx"> | |
// Create an application module for our demo. | |
angular.module( "Demo", [] ); | |
// --------------------------------------------------------------------------- // | |
// --------------------------------------------------------------------------- // | |
angular.module( "Demo" ).directive( | |
"bnHelloWorld", | |
function( $log ) { | |
// Return the directive definition object. | |
return({ | |
controller: Controller, | |
controllerAs: "vm", | |
link: link, | |
restrict: "A", | |
transclude: true, | |
scope: true, | |
template: | |
``` | |
<div class="container"> | |
<div class="header"> | |
<h2> | |
HTML <em>in</em> Your JavaScript?! | |
</h2> | |
</div> | |
<div class="content" ng-transclude> | |
<!-- Transcluded content will appear here. --> | |
</div> | |
<div ng-click="vm.cycleQuote()" class="footer"> | |
<strong>Inspiration</strong>: {{ vm.quote }} | |
</div> | |
</div> | |
``` | |
}); | |
// I control the HelloWorld component. | |
function Controller( $scope ) { | |
var vm = this; | |
var quoteIndex = 0; | |
var quotes = [ | |
"Asphinctersayswhat?", | |
"Ah, Nuprin. Little. Yellow. Different.", | |
"As you can see, it sucks as it cuts.", | |
"If you're gonna spew, spew into this.", | |
"Party on Wayne. Party on Garth.", | |
"Calgon - ancient Chinese secret.", | |
"I don't even own A gun, let alone the many guns that would necessitate a rack.", | |
"Game on!" | |
]; | |
vm.quote = quotes[ quoteIndex ]; | |
// Expose the public API. | |
vm.cycleQuote = cycleQuote; | |
// --- | |
// PUBLIC METHODS. | |
// --- | |
// I move on to the next quote in the collection. | |
function cycleQuote() { | |
if ( ++quoteIndex >= quotes.length ) { | |
quoteIndex = 0; | |
} | |
vm.quote = quotes[ quoteIndex ]; | |
} | |
} | |
// I bind the JavaScript events to the view-model of the component. | |
function link( scope, element, attributes ) { | |
element.mouseenter( | |
function handlerMouseenterEvent( event ) { | |
$log.info( "Moused into component." ); | |
} | |
); | |
var footer = element.find( "div.footer" ) | |
.hover( | |
function hoverOver() { | |
footer.addClass( "active" ); | |
}, | |
function hoverOut() { | |
footer.removeClass( "active" ); | |
} | |
) | |
; | |
} | |
} | |
); | |
</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 configureNgx( $, ng ) { | |
// Locate the root of the application. This demo assumes that there is only | |
// one AngularJS application on the page and that is uses the ng-app syntax. | |
var bootstrapElement = $( "*[ ng-app ]" ); | |
// Get the application module name - we'll need this to manually bootstrap | |
// the application after the page loads. | |
var moduleName = bootstrapElement.attr( "ng-app" ); | |
// Remove the ng-app attribute so that AngularJS doesn't automatically | |
// bootstrap the application before we've had a chance to parse our NGX scripts. | |
bootstrapElement.removeAttr( "ng-app" ); | |
// Once the DOM is ready, find the inline NGX scripts and convert them to JavaScript. | |
$( findAndParseNgxBlocks ); | |
// --- | |
// PRIVATE METHODS. | |
// --- | |
// I find all of the NGX block and convert them into JavaScript Script tags that get | |
// injected back into the page (where they are executed). Once this is done, the | |
// AngularJS application is bootstrapped. | |
function findAndParseNgxBlocks() { | |
// Convert all the NGX blocks to active Script elements. | |
$( "script[ type = 'text/ngx' ]" ) | |
.remove() | |
.map( | |
function convertToScript() { | |
var script = document.createElement( "script" ); | |
script.type = "text/javascript"; | |
script.text = parseNgx( this.innerHTML ); | |
return( script ); | |
} | |
) | |
.appendTo( "head" ) | |
; | |
// Once the script tags are all converted, bootstrap the AngularJS application. | |
ng.bootstrap( document, [ moduleName ] ); | |
} | |
// I parse the given NGX content into valid JavaScript content. For this demo, this | |
// consist of finding the "```" (triple back-tick) delimited values and converting | |
// them into single-lines of quoted text. | |
function parseNgx( ngxContent ) { | |
var templatePattern = /```([\w\W]*?)```/g; | |
var jsContent = ngxContent.replace( | |
templatePattern, | |
function( $0, template ) { | |
// Remove leading and trailing spaces from each line. | |
template = template.replace( /^\s+|\s$/gm, "" ); | |
// Escape any embedded double-quotes. | |
template = template.replace( /(")/g, "\\$1" ); | |
// Replace line-returns with spaces. | |
template = template.replace( /[\r\n]+/g, " " ); | |
// Quote the entire template value. | |
return( "\"" + $.trim( template ) + "\"" ); | |
} | |
); | |
return( jsContent ); | |
} | |
})( jQuery, angular ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment