Skip to content

Commit 784c1bd

Browse files
committed
finished screencast
1 parent f7b7e68 commit 784c1bd

File tree

5 files changed

+135
-110
lines changed

5 files changed

+135
-110
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Advanced Directives with Angular JS
2+
3+
Code for a screencast that examines some of the more advanced features in Angular, specifically Directives and how we can leverage the power of custom elements and attributes to map Domain Specific concepts through HTML, translate those into Value Objects in our Domain, and achieve rendered simple HTML output.
4+
5+
## Topics Covered:
6+
- html as a dsl
7+
- abstractions
8+
- $compile
9+
- $templateRequest
10+
- $templateCache
11+
- directive definition object
12+
- requiring other directives
13+
- directive communication ($scope.$broadcast, $scope.$on)

app_module.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
angular.module("app", []).run(function($templateRequest) {
22
$templateRequest("/templates/editor.html");
33
});
4-
5-

grid_directives.js

Lines changed: 106 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,109 @@
1-
angular.module("app")
2-
.directive("gridScreen", function($http) {
3-
return {
4-
restrict: "E",
5-
controller: function($scope) {
6-
this.setColumns = function(cols) {
7-
$scope.columns = cols;
8-
};
1+
// <grid-screen resource="/api/data.json">
2+
// <grid-columns>
3+
// <grid-column title="Product" field="product"></grid-column>
4+
// <grid-column title="Description" field="description"></grid-column>
5+
// <grid-column title="Cost" field="cost"></grid-column>
6+
// </grid-columns>
7+
// <grid with-inline-editor></grid>
8+
// </grid-screen>
99

10-
this.setEditor = function(editor) {
11-
$scope.columns.unshift(editor);
12-
};
13-
},
14-
link: function(scope, element, attributes) {
15-
$http.get(attributes.resource).success(function(response) {
16-
scope.rows = response.data;
17-
scope.$broadcast('ready-to-render', scope.rows, scope.columns);
18-
});
19-
}
20-
}
21-
})
22-
.directive("gridColumns", function() {
23-
return {
24-
restrict: "E",
25-
require: ['^gridScreen', 'gridColumns'],
26-
controller: function() {
27-
var columns = [];
28-
this.addColumn = function(col) {
29-
columns.push(col);
30-
};
10+
// 3 domain objects: editor, edit, columns, rows
3111

32-
this.getColumns = function() {
33-
return columns;
34-
};
35-
},
36-
link: function(scope, element, attributes, controllers) {
37-
var gridScreenController = controllers[0];
38-
var gridColumnsController = controllers[1];
39-
gridScreenController.setColumns(gridColumnsController.getColumns());
40-
}
41-
};
42-
})
43-
.directive("gridColumn", function() {
44-
return {
45-
restrict: "E",
46-
require: "^gridColumns",
47-
link: function(scope, element, attributes, gridColumnsController) {
48-
gridColumnsController.addColumn({title: attributes.title, field: attributes.field});
49-
}
50-
};
51-
})
52-
.directive("grid", function() {
53-
return {
54-
restrict: "E",
55-
templateUrl: "/templates/as_table.html",
56-
replace: true,
57-
controller: function($scope) {
58-
$scope.$on('ready-to-render', function(e, rows, columns) {
59-
$scope.rows = rows;
60-
$scope.columns = columns;
61-
});
62-
}
63-
};
64-
})
65-
.directive("withInlineEditor", function() {
66-
return {
67-
restrict: "A",
68-
require: "^gridScreen",
69-
link: function(scope, element, attributes, gridScreenController) {
70-
gridScreenController.setEditor({title: "Edit", field: ""});
71-
}
72-
};
73-
})
74-
.directive("editorInitializer", function($compile, $templateCache) {
75-
return {
76-
restrict: "E",
77-
scope: {
78-
row: "=",
79-
columns: "="
80-
},
81-
replace: true,
82-
templateUrl: "/templates/editor_initializer.html",
83-
controller: function($scope) {
84-
$scope.edit = function(row) {
85-
$scope.$broadcast('edit', row);
86-
};
87-
},
88-
link: function(scope, element, attributes) {
89-
scope.$on('edit', function(e, row) {
90-
var editor = $compile($templateCache.get("/templates/editor.html"))(scope);
91-
$(editor).insertAfter(element.parents("tr"));
92-
});
93-
}
12+
angular.module("app").directive("gridScreen", function($http) {
13+
return {
14+
restrict: 'E',
15+
controller: function($scope) {
16+
// columns, editor
17+
this.setEditor = function(editor) {
18+
$scope.cols.unshift(editor);
19+
};
20+
this.setColumns = function(cols) {
21+
$scope.cols = cols;
22+
};
23+
},
24+
link: function(scope, element, attributes) {
25+
$http.get(attributes.resource).success(function(response) {
26+
scope.rows = response.data;
27+
scope.$broadcast('ready-to-render', scope.rows, scope.cols);
28+
});
29+
}
30+
};
31+
});
32+
angular.module("app").directive("gridColumns", function() {
33+
return {
34+
restrict: 'E',
35+
require: ['^gridScreen', 'gridColumns'],
36+
controller: function() {
37+
var columns = [];
38+
this.addColumn = function(col) {
39+
columns.push(col);
40+
};
41+
this.getColumns = function() {
42+
return columns;
43+
};
44+
},
45+
link: function(scope, element, attributes, controllers) {
46+
var gridScreenController = controllers[0];
47+
var gridColumnsController = controllers[1];
48+
gridScreenController.setColumns(gridColumnsController.getColumns());
49+
console.log('linked gridColumns');
50+
}
51+
};
52+
});
53+
angular.module("app").directive("gridColumn", function() {
54+
return {
55+
restrict: 'E',
56+
require: '^gridColumns',
57+
link: function(scope, element, attributes, gridColumnsController) {
58+
gridColumnsController.addColumn({
59+
title: attributes.title,
60+
field: attributes.field
61+
});
62+
console.log('linked gridColumn', attributes.title);
63+
}
64+
};
65+
});
66+
angular.module("app").directive("grid", function() {
67+
return {
68+
restrict: 'E',
69+
templateUrl: "/templates/as_table.html",
70+
replace: true,
71+
controller: function($scope) {
72+
$scope.$on('ready-to-render', function(e, rows, cols) {
73+
$scope.rows = rows;
74+
$scope.cols = cols;
75+
});
76+
}
77+
};
78+
});
79+
angular.module("app").directive("withInlineEditor", function() {
80+
return {
81+
restrict: 'A',
82+
require: '^gridScreen',
83+
link: function(scope, element, attributes, gridScreenController) {
84+
gridScreenController.setEditor({
85+
title: "Edit",
86+
field: ""
87+
});
88+
console.log('linked withInlineEditor');
89+
}
90+
};
91+
});
92+
angular.module("app").directive("editorInitializer", function($compile, $templateCache) {
93+
return {
94+
restrict: 'E',
95+
templateUrl: '/templates/editor_initializer.html',
96+
controller: function($scope) {
97+
$scope.edit = function(row) {
98+
$scope.$broadcast('edit', row);
99+
};
100+
},
101+
link: function(scope, element, attributes) {
102+
scope.$on('edit', function(e, row) {
103+
var editor = $compile($templateCache.get("/templates/editor.html"))(scope);
104+
$(editor).insertAfter(element.parents("tr"));
105+
});
106+
console.log('linked editorInitializer');
94107
}
95-
});
108+
};
109+
});

templates/as_table.html

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
<table class="grid">
22
<thead>
33
<tr>
4-
<th ng-repeat="column in columns">{{column.title}}</th>
4+
<th ng-repeat="col in cols">{{col.title}}</th>
5+
<tbody>
6+
<tr ng-repeat="row in rows">
7+
<td ng-repeat="col in cols">
8+
<span ng-if="col.title !== 'Edit'">{{row[col.field]}}</span>
9+
<span ng-if="col.title == 'Edit'">
10+
<editor-initializer></editor-initializer>
11+
</span>
12+
</td>
13+
</tr>
14+
</tbody>
515
</tr>
616
</thead>
7-
<tbody>
8-
<tr ng-repeat="row in rows">
9-
<td ng-repeat="column in columns">
10-
<span ng-if="column.title !== 'Edit'">{{row[column.field]}}</span>
11-
<span ng-if="column.title === 'Edit'">
12-
<editor-initializer row="row" columns="columns"></editor-initializer>
13-
</span>
14-
</td>
15-
</tr>
16-
</tbody>
1717
</table>

templates/editor.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<tr class="editor-row">
2-
<td colspan="{{columns.length}}">
3-
<div ng-repeat="column in columns">
4-
<span ng-if="column.title !== 'Edit'">
2+
<td colspan="{{cols.length}}">
3+
<div ng-repeat="col in cols">
4+
<span ng-if="col.title !== 'Edit'">
55
<label>
6-
{{column.field}}
7-
<input type="text" ng-model="row[column.field]" />
6+
{{col.field}}
7+
<input type="text" ng-model="row[col.field]">
88
</label>
99
</span>
1010
</div>

0 commit comments

Comments
 (0)