Skip to content

Commit da559e6

Browse files
chore(html2js): generate more sensible template names.
1 parent a47e689 commit da559e6

File tree

16 files changed

+122
-52
lines changed

16 files changed

+122
-52
lines changed

1820EN_10_Code/01_alert_directive/directive.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ angular.module("alert-directive", [])
55
restrict:'EA',
66
replace: true,
77
template:
8-
'<div class="alert alert-block alert-{{type || \'info\'}}">' +
8+
'<div class="alert alert-{{type || \'info\'}}">' +
99
'<button type="button" class="close" ng-click="close()">&times;</button>' +
1010
'<div ng-transclude></div>' +
1111
'</div>',

1820EN_10_Code/01_alert_directive/index.html

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
<script src="app.js"></script>
1010
</head>
1111
<body>
12+
<div ng-init="type='success'">
13+
<div>{{type}}</div>
14+
<alert type="'info'">Look at {{type}}</alert>
15+
</div>
16+
1217
<div ng-controller="AlertController" class="well">
1318
<alert ng-repeat="alert in alerts" type="alert.type" close="closeAlert($index)">{{alert.msg}}</alert>
1419
<button class='btn' ng-click="addAlert()">Add Alert</button>

1820EN_10_Code/03_basic_accordion_directive/accordion.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ angular.module('accordion', [])
4040
restrict:'E',
4141
controller:'AccordionController',
4242
transclude: true,
43-
templateUrl: '1820EN_10_Code/03_basic_accordion_directive/template/accordion/accordion.html'
43+
templateUrl: 'accordion.html'
4444
};
4545
})
4646

@@ -51,7 +51,7 @@ angular.module('accordion', [])
5151
restrict:'E', // It will be an element
5252
transclude:true, // It transcludes the contents of the directive into the template
5353
replace: true, // The element containing the directive will be replaced with the template
54-
templateUrl:'1820EN_10_Code/03_basic_accordion_directive/template/accordion/accordion-group.html',
54+
templateUrl:'accordion-group.html',
5555
scope:{ heading:'@' }, // Create an isolated scope and mirror the heading attribute onto this scope
5656
link: function(scope, element, attrs, accordionCtrl) {
5757
accordionCtrl.addGroup(scope);

1820EN_10_Code/03_basic_accordion_directive/accordion.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ describe('accordion', function () {
22
var $scope;
33

44
beforeEach(module('accordion'));
5-
beforeEach(module('1820EN_10_Code/03_basic_accordion_directive/template/accordion/accordion-group.html'));
6-
beforeEach(module('1820EN_10_Code/03_basic_accordion_directive/template/accordion/accordion.html'));
5+
beforeEach(module('accordion-group.html'));
6+
beforeEach(module('accordion.html'));
77

88
beforeEach(inject(function ($rootScope) {
99
$scope = $rootScope;

1820EN_10_Code/03_basic_accordion_directive/app.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
angular.module('app', ['accordion', '1820EN_10_Code/03_basic_accordion_directive/template/accordion/accordion.html', '1820EN_10_Code/03_basic_accordion_directive/template/accordion/accordion-group.html'])
1+
angular.module('app', ['accordion', 'accordion.html', 'accordion-group.html'])
22

33
.controller('AccordionDemoCtrl', function ($scope) {
44
$scope.groups = [

1820EN_10_Code/03_basic_accordion_directive/template/accordion/accordion-group.html.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
angular.module("1820EN_10_Code/03_basic_accordion_directive/template/accordion/accordion-group.html", []).run(["$templateCache", function($templateCache) {
2-
$templateCache.put("1820EN_10_Code/03_basic_accordion_directive/template/accordion/accordion-group.html",
1+
angular.module("accordion-group.html", []).run(["$templateCache", function($templateCache) {
2+
$templateCache.put("accordion-group.html",
33
"<div class=\"accordion-group\">" +
44
" <div class=\"accordion-heading\" ><a class=\"accordion-toggle\" ng-click=\"isOpen = !isOpen\">{{heading}}</a></div>" +
55
" <div class=\"accordion-body\" ng-show=\"isOpen\">" +
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
angular.module("1820EN_10_Code/03_basic_accordion_directive/template/accordion/accordion.html", []).run(["$templateCache", function($templateCache) {
2-
$templateCache.put("1820EN_10_Code/03_basic_accordion_directive/template/accordion/accordion.html",
1+
angular.module("accordion.html", []).run(["$templateCache", function($templateCache) {
2+
$templateCache.put("accordion.html",
33
"<div class=\"accordion\" ng-transclude></div>");
44
}]);

1820EN_10_Code/04_field_directive/field-directive.js renamed to 1820EN_10_Code/04_field_directive/directive.js

+24-17
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
angular.module('field-directive', [
2-
'1820EN_10_Code/04_field_directive/template/input.html',
3-
'1820EN_10_Code/04_field_directive/template/textarea.html',
4-
'1820EN_10_Code/04_field_directive/template/select.html'
5-
])
1+
angular.module('field-directive', ['input.html', 'textarea.html', 'select.html'])
62

7-
.directive('field', function($compile, $http, $templateCache, $interpolate) {
3+
.factory('loadTemplate', function($http, $templateCache) {
4+
return function(template) {
5+
return $http.get(template, {cache:$templateCache}).then(function(response) {
6+
return angular.element(response.data);
7+
}, function(response) {
8+
throw new Error('Template not found: ' + template);
9+
});
10+
};
11+
})
12+
13+
.directive('field', function($compile, $http, $interpolate, loadTemplate) {
814

915
var findInputElement = function(element) {
1016
return angular.element(element.find('input')[0] || element.find('textarea')[0] || element.find('select')[0]);
@@ -28,26 +34,29 @@ angular.module('field-directive', [
2834
});
2935

3036
// Find the content that will go into the new label
37+
// (attribute trumps child element)
3138
var labelContent = '';
3239
if ( element.attr('label') ) {
40+
// Label is provided as an attribute on the <field> element
3341
labelContent = element.attr('label');
3442
element[0].removeAttribute('label');
35-
}
36-
if ( element.find('label')[0] ) {
43+
} else if ( element.find('label')[0] ) {
44+
// Label is provided as a <label> child element of the <field> element
3745
labelContent = element.find('label').html();
3846
}
3947
if ( !labelContent ) {
4048
throw new Error('No label provided');
4149
}
4250

51+
element.html('');
52+
4353
// Load up the template for this kind of field
44-
var template = attrs.template || 'input'; // Default to the simple input if none given
45-
var getFieldElement = $http.get('1820EN_10_Code/04_field_directive/template/' + template + '.html', {cache:$templateCache}).then(function(response) {
46-
var newElement = angular.element(response.data);
47-
var inputElement = findInputElement(newElement);
54+
var template = attrs.template || 'input.html'; // Default to the simple input if none given
55+
var getFieldElement = loadTemplate(template).then(function(newElement) {
4856

4957
// Copy over the attributes to the input element
50-
// At least the ng-model attribute must be copied because we can't use interpolation in the template
58+
// We can't use interpolation in the template for directives such as ng-model
59+
var inputElement = findInputElement(newElement);
5160
angular.forEach(element[0].attributes, function (attribute) {
5261
var value = attribute.value;
5362
var key = attribute.name;
@@ -95,10 +104,8 @@ angular.module('field-directive', [
95104
// (i.e. after any parent form element has been linked)
96105
// otherwise the new input won't pick up the FormController
97106
$compile(newElement)(childScope, function(clone) {
98-
// Place our new element after the original element
99-
element.after(clone);
100-
// Remove our original element
101-
element.remove();
107+
// Place our new element as a child of the original element
108+
element.append(clone);
102109
});
103110

104111
// Only after the new element has been compiled do we have access to the ngModelController
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
describe('field directive', function () {
2+
var scope, $compile, element;
3+
4+
beforeEach(module('field-directive'));
5+
beforeEach(inject(function ($rootScope, _$compile_) {
6+
scope = $rootScope;
7+
$compile = _$compile_;
8+
}));
9+
10+
describe('templates', function() {
11+
it('loads up a specified template', function() {});
12+
it('loads up a template called "input" if none specified', function() {});
13+
it('handles a missing template', function() {});
14+
});
15+
describe('attributes', function() {
16+
it('copies attributes from the directive to the input/select/textarea element of the template', function() {});
17+
it('interpolates the label attribute into the label element (of the template), if provided', function() {});
18+
it('transcludes the label element (child of the directive) contents into the label element (of the template), if provided', function() {});
19+
it('errors if neither an attribute nor element provide a label', function() {});
20+
});
21+
22+
});

1820EN_10_Code/04_field_directive/index.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<script src="../../lib/angular/1.0.4/angular.js"></script>
88

99
<!-- Load the field directive -->
10-
<script src="field-directive.js"></script>
10+
<script src="directive.js"></script>
1111

1212
<!-- Load up the templates -->
1313
<script src="template/input.html.js"></script>
@@ -24,13 +24,13 @@
2424
<validator key="required">My Text is required</validator>
2525
</field>
2626

27-
<field ng-model="myModel.myBigText" template="textarea" label="My Big Text" ng-maxlength="5" ng-minlength="2" required="true">
27+
<field ng-model="myModel.myBigText" template="textarea.html" label="My Big Text" ng-maxlength="5" ng-minlength="2" required="true">
2828
<validator key="maxlength">My Big Text must be less than 5</validator>
2929
<validator key="minlength">My Big Text must be greater than 2</validator>
3030
<validator key="required">My Big Text must be greater than 2</validator>
3131
</field>
3232

33-
<field ng-model="myModel.choice" template="select" label="Choose something" ng-options="x for x in ['A','B', 'C']"></field>
33+
<field ng-model="myModel.choice" template="select.html" label="Choose something" ng-options="x for x in ['A','B', 'C']"></field>
3434

3535
<pre>{{myModel | json}}</pre>
3636
</form>

1820EN_10_Code/04_field_directive/template/input.html.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
angular.module("1820EN_10_Code/04_field_directive/template/input.html", []).run(["$templateCache", function($templateCache) {
2-
$templateCache.put("1820EN_10_Code/04_field_directive/template/input.html",
1+
angular.module("input.html", []).run(["$templateCache", function($templateCache) {
2+
$templateCache.put("input.html",
33
"<div class=\"control-group\" ng-class=\"{'error' : $field.$invalid && $field.$dirty, 'success' : $field.$valid && $field.$dirty}\">" +
44
" <label class=\"control-label\" >{{label}}</label>" +
55
" <div class=\"controls\">" +

1820EN_10_Code/04_field_directive/template/select.html.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
angular.module("1820EN_10_Code/04_field_directive/template/select.html", []).run(["$templateCache", function($templateCache) {
2-
$templateCache.put("1820EN_10_Code/04_field_directive/template/select.html",
1+
angular.module("select.html", []).run(["$templateCache", function($templateCache) {
2+
$templateCache.put("select.html",
33
"<div class=\"control-group\" ng-class=\"{'error' : $field.$invalid && $field.$dirty, 'success' : $field.$valid && $field.$dirty}\">" +
44
" <label class=\"control-label\">{{label}}</label>" +
55
" <div class=\"controls\">" +

1820EN_10_Code/04_field_directive/template/textarea.html.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
angular.module("1820EN_10_Code/04_field_directive/template/textarea.html", []).run(["$templateCache", function($templateCache) {
2-
$templateCache.put("1820EN_10_Code/04_field_directive/template/textarea.html",
1+
angular.module("textarea.html", []).run(["$templateCache", function($templateCache) {
2+
$templateCache.put("textarea.html",
33
"<div class=\"control-group\" ng-class=\"{'error' : $field.$invalid && $field.$dirty, 'success' : $field.$valid && $field.$dirty}\">" +
44
" <label class=\"control-label\">{{label}}</label>" +
55
" <div class=\"controls\">" +
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>AngularJS Book - Chapter 10 - if directive (tests)</title>
6+
<link rel="stylesheet" href="../../lib/jasmine-1.3.0/jasmine.css">
7+
<script src="../../lib/jasmine-1.3.0/jasmine.js"></script>
8+
<script src="../../lib/jasmine-1.3.0/jasmine-html.js"></script>
9+
<script src="../../lib/angular/1.0.4/angular.js"></script>
10+
<script src="../../lib/angular/1.0.4/angular-mocks.js"></script>
11+
</head>
12+
<body>
13+
<script src="directive.js"></script>
14+
<script src="directive.spec.js"></script>
15+
<script>
16+
var jasmineEnv = jasmine.getEnv();
17+
jasmineEnv.addReporter(new jasmine.HtmlReporter());
18+
jasmineEnv.execute();
19+
</script>
20+
</body>
21+
</html>

build/html2js.js

+29-14
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,37 @@ module.exports = function (grunt) {
1414
return p;
1515
};
1616

17-
grunt.registerTask('html2js', 'Generate js version of html template.', function() {
18-
this.requiresConfig('html2js.src');
19-
var files = grunt.file.expandFiles(grunt.config.process('html2js.src'));
20-
var base = grunt.config.process('html2js.base') || '.';
21-
var dest = grunt.config.process('html2js.dest') || '.';
22-
var templates = [];
17+
grunt.registerHelper('html2js', function(files, base, dest, prefix) {
18+
var templateList = [];
19+
prefix = prefix || '';
2320
files.forEach(function(file) {
24-
var id = normalizePath(path.relative(base, file));
25-
templates.push("'" + id + "'");
26-
grunt.file.write(path.resolve(dest, id + '.js'), grunt.template.process(TPL, {
27-
id: id,
21+
var templatePath = normalizePath(path.relative(base || path.dirname(file), file));
22+
var templateName = prefix + templatePath;
23+
var destPath = path.resolve(dest || path.dirname(file), templatePath + '.js');
24+
var template = grunt.template.process(TPL, {
25+
id: templateName,
2826
content: escapeContent(grunt.file.read(file))
29-
}));
27+
});
28+
templateList.push("'" + templateName + "'");
29+
grunt.file.write(destPath, template);
3030
});
31-
grunt.file.write(path.resolve(dest,'templates.js'), grunt.template.process(templateModule, {
32-
templates: templates.join(', ')
33-
}));
31+
32+
// Only write out a super module if the dest path was provided
33+
if ( dest ) {
34+
grunt.file.write(path.resolve(dest,'templates.js'), grunt.template.process(templateModule, {
35+
templates: templateList.join(', ')
36+
}));
37+
}
38+
39+
return templateList;
40+
});
41+
42+
grunt.registerTask('html2js', 'Generate js version of html template.', function() {
43+
this.requiresConfig('html2js.src');
44+
var files = grunt.file.expandFiles(grunt.config.process('html2js.src'));
45+
var base = grunt.config.process('html2js.base');
46+
var dest = grunt.config.process('html2js.dest');
47+
var prefix = grunt.config.process('html2js.prefix');
48+
grunt.helper('html2js', files, base, dest, prefix);
3449
});
3550
};

grunt.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ module.exports = function (grunt) {
66
html2js: {
77
src: ['1820EN_*/**/template/**/*.html']
88
},
9-
lint:{
9+
lint: {
1010
files:['grunt.js', '1820EN_*/**/*.js']
1111
}
1212
});
1313

1414
// Default task
15-
grunt.registerTask('default', 'lint test');
15+
grunt.registerTask('default', 'lint html2js test');
1616

1717
// Testacular configuration
1818
function runTestacular(command, options) {

0 commit comments

Comments
 (0)