SlideShare a Scribd company logo
Inside The AngularJS
Directive Compiler
Tero Parviainen
@teropa
Directives
“Angular attempts to minimize the impedance
mismatch between document centric HTML
and what an application needs by creating
new HTML constructs.
Angular teaches the browser new syntax
through a construct we call directives.”
https://docs.angularjs.org/guide/introduction
<body ng-app="myApp">	
<main-navigation>	
</main-navigation>	
<login-form orientation="vertical">	
</login-form>	
<news-feed max-items="10">	
</news-feed>	
</body>
{
priority: 0,
terminal: false,
template: '<div></div>',
templateNamespace: 'html',
replace: false,
multiElement: false,
transclude: false,
restrict: 'A',
scope: false,
controller: 'MyCtrl',
controllerAs: 'myCtrl',
bindToController: true,
require: '^parentCtrl',
compile: function(el) {
return {
pre: function(scope, el, attrs) { },
post: function(scope, el, attrs) { }
}
}
}
src/ng/compile.js
•  1307 lines of code
•  84 functions
•  Compilation & linking
•  Attribute management
•  Controllers
•  Isolate bindings
•  Templates & transclusion
https://github.com/es-analysis/plato
Learning by Imitation
1.  Compilation
2.  Linking
3.  Inheritance
4.  Isolation
1.  Compilation
2.  Linking
3.  Inheritance
4.  Isolation
The Directive Compiler
$compile
Directives
+
DOM
Compiled
DOM
$compileProvider.directive('myClass', function() {
return {
compile: function(element) {
element.addClass('decorated');
}
};
});
Directive Registration
<div id="root">
<div my-class></div>
</div>
Directive Usage
var root = document.querySelector('#root');
var $root = angular.element(root);
$compile($root);
Compilation
The Compile Provider
function $CompileProvider() {
this.directive = function(name, factory) {
};
}
Directive Registration
function $CompileProvider() {
var directives = {};
this.directive = function(name, factory) {
directives[name] = directives[name] || [];
directives[name].push(factory());
};
}
Constructing $compile
function $CompileProvider() {
var directives = {};
this.directive = function(name, factory) {
directives[name] = directives[name] || [];
directives[name].push(factory());
};
this.$get = function() {
return function $compile(element) {
};
};
}
The compileNode helper function
this.$get = function() {
function compileNode(element) {
}
return function $compile(element) {
compileNode(element);
};
};
Collecting Directives
this.$get = function() {
function collectDirectives(element) {
}
function compileNode(element) {
var directives = collectDirectives(element);
}
return function $compile(element) {
compileNode(element);
};
};
Three Collection Strategies
this.$get = function() {
function collectDirectives(element) {
return
collectElementDirectives(element)
.concat(collectAttrDirectives(element))
.concat(collectClassDirectives(element));
}
function compileNode(element) {
var directives = collectDirectives(element);
}
return function $compile(element) {
compileNode(element);
};
};
Element Directives
function collectElementDirectives(element) {
var elName = element[0].nodeName;
var directiveName = _.camelCase(elName);
return directives[directiveName] || [];
}
Attribute Directives
function collectAttrDirectives(element) {
var result = [];
_.each(element[0].attributes, function(attr) {
var dirName = _.camelCase(attr.name);
result = result.concat(directives[dirName] || []);
});
return result;
}
Class Directives
function collectClassDirectives(element) {
var result = [];
_.each(element[0].classList, function(cName) {
var dirName = _.camelCase(cName);
result = result.concat(directives[dirName] || []);
});
return result;
}
Applying The Directives
function compileNode(element) {
var directives = collectDirectives(element);
directives.forEach(function(directive) {
directive.compile(element);
});
}
Recursing to Child Nodes
function compileNode(element) {
var directives = collectDirectives(element);
directives.forEach(function(directive) {
directive.compile(element);
});
element.children().forEach(compileNode);
}
1.  Compilation
2.  Linking
3.  Inheritance
4.  Isolation
Scopes
• Application data + behavior
• Change detection
• Events
The Directive Compiler And Linker
$compile
Directives
+
DOM
Compiled DOM
+
Linker
Linker
Linked
DOM
Compiled DOM
+
Scope
$compileProvider.directive('myClass', function() {
return {
compile: function(element) {
return function link(scope, element) {
element.addClass(scope.theClass);
};
}
};
});
Directive with a Link Function
var root = document.querySelector('#root');
var $root = angular.element(root);
var linkFunction = $compile($root);
$rootScope.theClass = 'decorated';
linkFunction($rootScope);
Linking
The Node Link Function
function compileNode(element) {
var directives = collectDirectives(element);
directives.forEach(function(directive) {
directive.compile(element);
});
element.children().forEach(compileNode);
return function nodeLinkFn(scope) {
};
}
return function $compile(element) {
return compileNode(element);
};
Collect Link Functions
function compileNode(element) {
var directives = collectDirectives(element),
linkFns = [];
directives.forEach(function(directive) {
var linkFn = directive.compile(element);
linkFns.push(linkFn);
});
element.children().forEach(compileNode);
return function nodeLinkFn(scope) {
};
}
Apply Link Functions
function compileNode(element) {
var directives = collectDirectives(element),
linkFns = [];
directives.forEach(function(directive) {
var linkFn = directive.compile(element);
linkFns.push(linkFn);
});
element.children().forEach(compileNode);
return function nodeLinkFn(scope) {
linkFns.forEach(function(linkFn) {
linkFn(scope, element);
});
};
}
Collect Child Link Functions
function compileNode(element) {
var directives = collectDirectives(element),
linkFns = [];
directives.forEach(function(directive) {
var linkFn = directive.compile(element);
linkFns.push(linkFn);
});
var childLinkFns =
element.children().map(compileNode);
return function nodeLinkFn(scope) {
linkFns.forEach(function(linkFn) {
linkFn(scope, element);
});
};
}
Apply Child Link Functions
function compileNode(element) {
var directives = collectDirectives(element),
linkFns = [];
directives.forEach(function(directive) {
var linkFn = directive.compile(element);
linkFns.push(linkFn);
});
var childLinkFns =
element.children().map(compileNode);
return function nodeLinkFn(scope) {
childLinkFns.forEach(function(childLinkFn) {
childLinkFn(scope);
});
linkFns.forEach(function(linkFn) {
linkFn(scope, element);
});
};
}
1.  Compilation
2.  Linking
3.  Inheritance
4.  Isolation
Scope Hierarchy
$rootScope
$scope $scope
$scope
Scope Hierarchy vs. DOM Hierarchy
<article ng-app="myApp">
<section ng-controller="..."></section>
<section ng-controller="...">
<div ng-controller="...">
</div>
</section>
</article> $rootScope
$scope $scope
$scope
article
section section
div
$compileProvider.directive('myClass', function() {
return {
scope: true,
compile: function(element) {
return function link(scope, element) {
scope.counter = 0;
element.on('click', function() {
scope.counter++;
});
};
}
};
});
Directive Requests a Scope
Remember The “New Scope Directive”
function compileNode(element) {
var directives = collectDirectives(element),
linkFns = [],
newScopeDir;
directives.forEach(function(directive) {
var linkFn = directive.compile(element);
linkFns.push(linkFn);
if (directive.scope) {
if (newScopeDir) {
throw 'No more than 1 new scope plz!';
}
newScopeDir = directive;
}
});
// ...
}
Make a new scope during linking
return function nodeLinkFn(scope) {
if (newScopeDir) {
scope = scope.$new();
}
childLinkFns.forEach(function(childLinkFn) {
childLinkFn(scope);
});
linkFns.forEach(function(linkFn) {
linkFn(scope, element);
});
};
1.  Compilation
2.  Linking
3.  Inheritance
4.  Isolation
$rootScope
$scope $scope
$scope
Isolate Scopes
Isolate Bindings
$rootScope
$scope $scope
$scope
expression
attribute
Directive with Isolate Scope & Bindings
<div click-logger="'Hello!'"></div>
$compileProvider.directive('clickLogger', function() {
return {
scope: {
message: '=clickLogger'
},
compile: function(element) {
return function link(scope, element) {
scope.counter = 0;
element.on('click', function() {
console.log(scope.message);
});
};
}
};
});
Remember The “Iso Scope Directive”
function compileNode(element) {
var directives = collectDirectives(element),
linkFns = [],
newScopeDir, newIsoScopeDir;
directives.forEach(function(directive) {
var linkFn = directive.compile(element);
linkFns.push(linkFn);
if (directive.scope) {
if (newScopeDir || newIsoScopeDir) {
throw 'No more than 1 new scope plz!';
}
if (_.isObject(directive.scope)) {
newIsoScopeDir = directive;
} else {
newScopeDir = directive;
}
}
});
// ...
}
Create Isolate Scope During Linking
return function nodeLinkFn(scope) {
var isoScope;
if (newScopeDir) {
scope = scope.$new();
}
if (newIsoScopeDir) {
isoScope = scope.$new(true);
}
childLinkFns.forEach(function(childLinkFn) {
childLinkFn(scope);
});
linkFns.forEach(function(linkFn) {
linkFn(scope, element);
});
};
Remember Link Function Directives
function compileNode(element) {
var directives = collectDirectives(element),
linkFns = [],
newScopeDir, newIsoScopeDir;
directives.forEach(function(directive) {
var linkFn = directive.compile(element);
linkFn.directive = directive;
linkFns.push(linkFn);
if (directive.scope) {
if (newScopeDir || newIsoScopeDir) {
throw 'No more than 1 new scope plz!';
}
if (_.isObject(directive.scope)) {
newIsoScopeDir = directive;
} else {
newScopeDir = directive;
}
}
});
// ...
Apply Isolate Scope
return function nodeLinkFn(scope) {
var isoScope;
if (newScopeDir) {
scope = scope.$new();
}
if (newIsoScopeDir) {
isoScope = scope.$new(true);
}
childLinkFns.forEach(function(childLinkFn) {
childLinkFn(scope);
});
linkFns.forEach(function(linkFn) {
var isIso = (linkFn.directive === newIsoScopeDir);
linkFn(isIso ? isoScope : scope, element);
});
};
Isolate Bindings
<div click-logger="'Hello!'"></div>
$compileProvider.directive('clickLogger', function() {
return {
scope: {
message: '=clickLogger'
},
compile: function(element) {
return function link(scope, element) {
scope.counter = 0;
element.on('click', function() {
console.log(scope.message);
});
};
}
};
});
Loop Over Isolate Bindings
return function nodeLinkFn(scope) {
var isoScope;
if (newScopeDir) {
scope = scope.$new();
}
if (newIsoScopeDir) {
isoScope = scope.$new(true);
_.forOwn(
newIsoScopeDir.scope,
function(spec, scopeName) {
}
);
}
// ...
};
Get Attribute Expression
if (newIsoScopeDir) {
isoScope = scope.$new(true);
_.forOwn(
newIsoScopeDir.scope,
function(spec, scopeName) {
var attrName = spec.match(/^=(.*)/)[1];
var denormalized = _.kebabCase(attrName);
var expr = element.attr(denormalized);
}
);
}
Watch & Bind The Expression
if (newIsoScopeDir) {
isoScope = scope.$new(true);
_.forOwn(
newIsoScopeDir.scope,
function(spec, scopeName) {
var attrName = spec.match(/^=(.*)/)[1];
var denormalized = _.kebabCase(attrName);
var expr = element.attr(denormalized);
scope.$watch(expr, function(newValue) {
isoScope[scopeName] = newValue;
});
}
);
}
Two-Way Data Binding
$rootScope
$scope $scope
$scope
expression
attribute
Two
directions
Parse Expression String to Function
if (newIsoScopeDir) {
isoScope = scope.$new(true);
_.forOwn(
newIsoScopeDir.scope,
function(spec, scopeName) {
var attrName = spec.match(/^=(.*)/)[1];
var denormalized = _.kebabCase(attrName);
var expr = element.attr(denormalized);
var exprFn = $parse(expr);
scope.$watch(exprFn, function(newValue) {
isoScope[scopeName] = newValue;
});
}
);
}
Refactor The Watcher
if (newIsoScopeDir) {
isoScope = scope.$new(true);
_.forOwn(
newIsoScopeDir.scope,
function(spec, scopeName) {
var attrName = spec.match(/^=(.*)/)[1];
var denormalized = _.kebabCase(attrName);
var expr = element.attr(denormalized);
var exprFn = $parse(expr);
scope.$watch(function() {
var newParentValue = exprFn(scope);
var childValue = isoScope[scopeName];
if (newParentValue !== childValue) {
isoScope[scopeName] = newParentValue;
}
});
}
);
}
Track The Parent Value
_.forOwn(
newIsoScopeDir.scope,
function(spec, scopeName) {
var attrName = spec.match(/^=(.*)/)[1];
var denormalized = _.kebabCase(attrName);
var expr = element.attr(denormalized);
var exprFn = $parse(expr);
var parentValue;
scope.$watch(function() {
var newParentValue = exprFn(scope);
var childValue = isoScope[scopeName];
if (newParentValue !== childValue) {
isoScope[scopeName] = newParentValue;
}
parentValue = newParentValue;
});
}
);
Check for Parent vs. Child Change
var parentValue;
scope.$watch(function() {
var newParentValue = exprFn(scope);
var childValue = isoScope[scopeName];
if (newParentValue !== childValue) {
if (newParentValue !== parentValue) {
isoScope[scopeName] = newParentValue;
} else {
}
}
parentValue = newParentValue;
});
Propagate Change Up
var parentValue;
scope.$watch(function() {
var newParentValue = exprFn(scope);
var childValue = isoScope[scopeName];
if (newParentValue !== childValue) {
if (newParentValue !== parentValue) {
isoScope[scopeName] = newParentValue;
} else {
exprFn.assign(scope, childValue);
newParentValue = childValue;
}
}
parentValue = newParentValue;
});
1.  Compilation
2.  Linking
3.  Inheritance
4.  Isolation
teropa.info
-75% off list price
with code
”FRAMEWORKSDAYS”
Ad

More Related Content

What's hot (20)

Dependency injection in scala
Dependency injection in scalaDependency injection in scala
Dependency injection in scala
Michal Bigos
 
Angular mix chrisnoring
Angular mix chrisnoringAngular mix chrisnoring
Angular mix chrisnoring
Christoffer Noring
 
BeScala - Scala Guice
BeScala -  Scala GuiceBeScala -  Scala Guice
BeScala - Scala Guice
BeScala
 
Test-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsTest-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS Applications
FITC
 
Building Smart Async Functions For Mobile
Building Smart Async Functions For MobileBuilding Smart Async Functions For Mobile
Building Smart Async Functions For Mobile
Glan Thomas
 
How to implement g rpc services in nodejs
How to implement g rpc services in nodejsHow to implement g rpc services in nodejs
How to implement g rpc services in nodejs
Katy Slemon
 
Durable functions
Durable functionsDurable functions
Durable functions
명신 김
 
Angular Schematics
Angular SchematicsAngular Schematics
Angular Schematics
Christoffer Noring
 
Java script advance-auroskills (2)
Java script advance-auroskills (2)Java script advance-auroskills (2)
Java script advance-auroskills (2)
BoneyGawande
 
Protocol-Oriented Networking
Protocol-Oriented NetworkingProtocol-Oriented Networking
Protocol-Oriented Networking
Mostafa Amer
 
Opinionated AngularJS
Opinionated AngularJSOpinionated AngularJS
Opinionated AngularJS
prabhutech
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
andyrobinson8
 
Java script – basic auroskills (2)
Java script – basic   auroskills (2)Java script – basic   auroskills (2)
Java script – basic auroskills (2)
BoneyGawande
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your App
Luca Mearelli
 
Angular 2 introduction
Angular 2 introductionAngular 2 introduction
Angular 2 introduction
Christoffer Noring
 
Second Level Cache in JPA Explained
Second Level Cache in JPA ExplainedSecond Level Cache in JPA Explained
Second Level Cache in JPA Explained
Patrycja Wegrzynowicz
 
Graphql, REST and Apollo
Graphql, REST and ApolloGraphql, REST and Apollo
Graphql, REST and Apollo
Christoffer Noring
 
To Batch Or Not To Batch
To Batch Or Not To BatchTo Batch Or Not To Batch
To Batch Or Not To Batch
Luca Mearelli
 
Java9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadJava9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidad
David Gómez García
 
Controlling The Cloud With Python
Controlling The Cloud With PythonControlling The Cloud With Python
Controlling The Cloud With Python
Luca Mearelli
 
Dependency injection in scala
Dependency injection in scalaDependency injection in scala
Dependency injection in scala
Michal Bigos
 
BeScala - Scala Guice
BeScala -  Scala GuiceBeScala -  Scala Guice
BeScala - Scala Guice
BeScala
 
Test-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsTest-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS Applications
FITC
 
Building Smart Async Functions For Mobile
Building Smart Async Functions For MobileBuilding Smart Async Functions For Mobile
Building Smart Async Functions For Mobile
Glan Thomas
 
How to implement g rpc services in nodejs
How to implement g rpc services in nodejsHow to implement g rpc services in nodejs
How to implement g rpc services in nodejs
Katy Slemon
 
Durable functions
Durable functionsDurable functions
Durable functions
명신 김
 
Java script advance-auroskills (2)
Java script advance-auroskills (2)Java script advance-auroskills (2)
Java script advance-auroskills (2)
BoneyGawande
 
Protocol-Oriented Networking
Protocol-Oriented NetworkingProtocol-Oriented Networking
Protocol-Oriented Networking
Mostafa Amer
 
Opinionated AngularJS
Opinionated AngularJSOpinionated AngularJS
Opinionated AngularJS
prabhutech
 
Java script – basic auroskills (2)
Java script – basic   auroskills (2)Java script – basic   auroskills (2)
Java script – basic auroskills (2)
BoneyGawande
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your App
Luca Mearelli
 
To Batch Or Not To Batch
To Batch Or Not To BatchTo Batch Or Not To Batch
To Batch Or Not To Batch
Luca Mearelli
 
Java9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadJava9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidad
David Gómez García
 
Controlling The Cloud With Python
Controlling The Cloud With PythonControlling The Cloud With Python
Controlling The Cloud With Python
Luca Mearelli
 

Viewers also liked (20)

AngularJS Compile Process
AngularJS Compile ProcessAngularJS Compile Process
AngularJS Compile Process
Eyal Vardi
 
"Spring Boot. Boot up your development" Сергей Моренец
"Spring Boot. Boot up your development" Сергей Моренец"Spring Boot. Boot up your development" Сергей Моренец
"Spring Boot. Boot up your development" Сергей Моренец
Fwdays
 
"После OOD: как моделировать предметную область в пост-объектном мире" Руслан...
"После OOD: как моделировать предметную область в пост-объектном мире" Руслан..."После OOD: как моделировать предметную область в пост-объектном мире" Руслан...
"После OOD: как моделировать предметную область в пост-объектном мире" Руслан...
Fwdays
 
Designing for Privacy
Designing for PrivacyDesigning for Privacy
Designing for Privacy
exultantwarning51
 
Michael North "The Road to Native Web Components"
Michael North "The Road to Native Web Components"Michael North "The Road to Native Web Components"
Michael North "The Road to Native Web Components"
Fwdays
 
Алексей Рыбаков: "Wearable OS год спустя: Apple Watch 2.0, Android Wear 5.1.1...
Алексей Рыбаков: "Wearable OS год спустя: Apple Watch 2.0, Android Wear 5.1.1...Алексей Рыбаков: "Wearable OS год спустя: Apple Watch 2.0, Android Wear 5.1.1...
Алексей Рыбаков: "Wearable OS год спустя: Apple Watch 2.0, Android Wear 5.1.1...
Fwdays
 
Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...
Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...
Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...
Fwdays
 
Сергей Яковлев "Phalcon 2 - стабилизация и производительность"
Сергей Яковлев "Phalcon 2 - стабилизация и производительность"Сергей Яковлев "Phalcon 2 - стабилизация и производительность"
Сергей Яковлев "Phalcon 2 - стабилизация и производительность"
Fwdays
 
Александр Воронов | Building CLI with Swift
Александр Воронов | Building CLI with SwiftАлександр Воронов | Building CLI with Swift
Александр Воронов | Building CLI with Swift
Fwdays
 
Евгений Жарков AngularJS: Good parts
Евгений Жарков AngularJS: Good partsЕвгений Жарков AngularJS: Good parts
Евгений Жарков AngularJS: Good parts
Fwdays
 
Fighting Fat Models (Богдан Гусев)
Fighting Fat Models (Богдан Гусев)Fighting Fat Models (Богдан Гусев)
Fighting Fat Models (Богдан Гусев)
Fwdays
 
"Красная книга веб-разработчика" Виктор Полищук
"Красная книга веб-разработчика" Виктор Полищук"Красная книга веб-разработчика" Виктор Полищук
"Красная книга веб-разработчика" Виктор Полищук
Fwdays
 
Илья Прукко: "Как дизайнеру не становиться художником"
Илья Прукко: "Как дизайнеру не становиться художником"Илья Прукко: "Как дизайнеру не становиться художником"
Илья Прукко: "Как дизайнеру не становиться художником"
Fwdays
 
Скрам и Канбан: применимость самых распространенных методов организации умств...
Скрам и Канбан: применимость самых распространенных методов организации умств...Скрам и Канбан: применимость самых распространенных методов организации умств...
Скрам и Канбан: применимость самых распространенных методов организации умств...
Fwdays
 
Швейцарія, масштабування Scrum і розподілені команди от Романа Сахарова
Швейцарія, масштабування Scrum і розподілені команди от Романа СахароваШвейцарія, масштабування Scrum і розподілені команди от Романа Сахарова
Швейцарія, масштабування Scrum і розподілені команди от Романа Сахарова
Fwdays
 
Андрей Шумада | Tank.ly
Андрей Шумада | Tank.ly Андрей Шумада | Tank.ly
Андрей Шумада | Tank.ly
Fwdays
 
Александр Махомет "Feature Flags. Уменьшаем риски при выпуске изменений"
Александр Махомет "Feature Flags. Уменьшаем риски при выпуске изменений" Александр Махомет "Feature Flags. Уменьшаем риски при выпуске изменений"
Александр Махомет "Feature Flags. Уменьшаем риски при выпуске изменений"
Fwdays
 
Трансформация команды: от инди разработки к играм с коммерческой успешностью
Трансформация команды: от инди разработки к играм с коммерческой успешностьюТрансформация команды: от инди разработки к играм с коммерческой успешностью
Трансформация команды: от инди разработки к играм с коммерческой успешностью
Fwdays
 
Светлана Старикова "Building a self-managing team: why you should not have e...
 Светлана Старикова "Building a self-managing team: why you should not have e... Светлана Старикова "Building a self-managing team: why you should not have e...
Светлана Старикова "Building a self-managing team: why you should not have e...
Fwdays
 
Евгений Обрезков "Behind the terminal"
Евгений Обрезков "Behind the terminal"Евгений Обрезков "Behind the terminal"
Евгений Обрезков "Behind the terminal"
Fwdays
 
AngularJS Compile Process
AngularJS Compile ProcessAngularJS Compile Process
AngularJS Compile Process
Eyal Vardi
 
"Spring Boot. Boot up your development" Сергей Моренец
"Spring Boot. Boot up your development" Сергей Моренец"Spring Boot. Boot up your development" Сергей Моренец
"Spring Boot. Boot up your development" Сергей Моренец
Fwdays
 
"После OOD: как моделировать предметную область в пост-объектном мире" Руслан...
"После OOD: как моделировать предметную область в пост-объектном мире" Руслан..."После OOD: как моделировать предметную область в пост-объектном мире" Руслан...
"После OOD: как моделировать предметную область в пост-объектном мире" Руслан...
Fwdays
 
Michael North "The Road to Native Web Components"
Michael North "The Road to Native Web Components"Michael North "The Road to Native Web Components"
Michael North "The Road to Native Web Components"
Fwdays
 
Алексей Рыбаков: "Wearable OS год спустя: Apple Watch 2.0, Android Wear 5.1.1...
Алексей Рыбаков: "Wearable OS год спустя: Apple Watch 2.0, Android Wear 5.1.1...Алексей Рыбаков: "Wearable OS год спустя: Apple Watch 2.0, Android Wear 5.1.1...
Алексей Рыбаков: "Wearable OS год спустя: Apple Watch 2.0, Android Wear 5.1.1...
Fwdays
 
Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...
Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...
Павел Тайкало: "Optimistic Approach : How to show results instead spinners wi...
Fwdays
 
Сергей Яковлев "Phalcon 2 - стабилизация и производительность"
Сергей Яковлев "Phalcon 2 - стабилизация и производительность"Сергей Яковлев "Phalcon 2 - стабилизация и производительность"
Сергей Яковлев "Phalcon 2 - стабилизация и производительность"
Fwdays
 
Александр Воронов | Building CLI with Swift
Александр Воронов | Building CLI with SwiftАлександр Воронов | Building CLI with Swift
Александр Воронов | Building CLI with Swift
Fwdays
 
Евгений Жарков AngularJS: Good parts
Евгений Жарков AngularJS: Good partsЕвгений Жарков AngularJS: Good parts
Евгений Жарков AngularJS: Good parts
Fwdays
 
Fighting Fat Models (Богдан Гусев)
Fighting Fat Models (Богдан Гусев)Fighting Fat Models (Богдан Гусев)
Fighting Fat Models (Богдан Гусев)
Fwdays
 
"Красная книга веб-разработчика" Виктор Полищук
"Красная книга веб-разработчика" Виктор Полищук"Красная книга веб-разработчика" Виктор Полищук
"Красная книга веб-разработчика" Виктор Полищук
Fwdays
 
Илья Прукко: "Как дизайнеру не становиться художником"
Илья Прукко: "Как дизайнеру не становиться художником"Илья Прукко: "Как дизайнеру не становиться художником"
Илья Прукко: "Как дизайнеру не становиться художником"
Fwdays
 
Скрам и Канбан: применимость самых распространенных методов организации умств...
Скрам и Канбан: применимость самых распространенных методов организации умств...Скрам и Канбан: применимость самых распространенных методов организации умств...
Скрам и Канбан: применимость самых распространенных методов организации умств...
Fwdays
 
Швейцарія, масштабування Scrum і розподілені команди от Романа Сахарова
Швейцарія, масштабування Scrum і розподілені команди от Романа СахароваШвейцарія, масштабування Scrum і розподілені команди от Романа Сахарова
Швейцарія, масштабування Scrum і розподілені команди от Романа Сахарова
Fwdays
 
Андрей Шумада | Tank.ly
Андрей Шумада | Tank.ly Андрей Шумада | Tank.ly
Андрей Шумада | Tank.ly
Fwdays
 
Александр Махомет "Feature Flags. Уменьшаем риски при выпуске изменений"
Александр Махомет "Feature Flags. Уменьшаем риски при выпуске изменений" Александр Махомет "Feature Flags. Уменьшаем риски при выпуске изменений"
Александр Махомет "Feature Flags. Уменьшаем риски при выпуске изменений"
Fwdays
 
Трансформация команды: от инди разработки к играм с коммерческой успешностью
Трансформация команды: от инди разработки к играм с коммерческой успешностьюТрансформация команды: от инди разработки к играм с коммерческой успешностью
Трансформация команды: от инди разработки к играм с коммерческой успешностью
Fwdays
 
Светлана Старикова "Building a self-managing team: why you should not have e...
 Светлана Старикова "Building a self-managing team: why you should not have e... Светлана Старикова "Building a self-managing team: why you should not have e...
Светлана Старикова "Building a self-managing team: why you should not have e...
Fwdays
 
Евгений Обрезков "Behind the terminal"
Евгений Обрезков "Behind the terminal"Евгений Обрезков "Behind the terminal"
Евгений Обрезков "Behind the terminal"
Fwdays
 
Ad

Similar to "Inside The AngularJS Directive Compiler" by Tero Parviainen (20)

Angular.js Primer in Aalto University
Angular.js Primer in Aalto UniversityAngular.js Primer in Aalto University
Angular.js Primer in Aalto University
SC5.io
 
Angular custom directives
Angular custom directivesAngular custom directives
Angular custom directives
Alexe Bogdan
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
Eyal Vardi
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
Eyal Vardi
 
AngularJS Basic Training
AngularJS Basic TrainingAngularJS Basic Training
AngularJS Basic Training
Cornel Stefanache
 
Basics of angular directive (Part - 1)
Basics of angular directive (Part - 1)Basics of angular directive (Part - 1)
Basics of angular directive (Part - 1)
Vijay Kani
 
AngularJs-training
AngularJs-trainingAngularJs-training
AngularJs-training
Pratchaya Suputsopon
 
AngularJS Custom Directives
AngularJS Custom DirectivesAngularJS Custom Directives
AngularJS Custom Directives
yprodev
 
Custom AngularJS Directives
Custom AngularJS DirectivesCustom AngularJS Directives
Custom AngularJS Directives
yprodev
 
Angular Presentation
Angular PresentationAngular Presentation
Angular Presentation
Adam Moore
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
Ben Lin
 
Introduction to AngularJS For WordPress Developers
Introduction to AngularJS For WordPress DevelopersIntroduction to AngularJS For WordPress Developers
Introduction to AngularJS For WordPress Developers
Caldera Labs
 
Angular js
Angular jsAngular js
Angular js
Behind D Walls
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
Juliana Lucena
 
angularJs Workshop
angularJs WorkshopangularJs Workshop
angularJs Workshop
Ran Wahle
 
"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović
JS Belgrade
 
Extend GraphQL with directives
Extend GraphQL with directivesExtend GraphQL with directives
Extend GraphQL with directives
Greg Bergé
 
AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014
Ran Wahle
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
Daniel Bryant
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For Managers
AgileThought
 
Angular.js Primer in Aalto University
Angular.js Primer in Aalto UniversityAngular.js Primer in Aalto University
Angular.js Primer in Aalto University
SC5.io
 
Angular custom directives
Angular custom directivesAngular custom directives
Angular custom directives
Alexe Bogdan
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
Eyal Vardi
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
Eyal Vardi
 
Basics of angular directive (Part - 1)
Basics of angular directive (Part - 1)Basics of angular directive (Part - 1)
Basics of angular directive (Part - 1)
Vijay Kani
 
AngularJS Custom Directives
AngularJS Custom DirectivesAngularJS Custom Directives
AngularJS Custom Directives
yprodev
 
Custom AngularJS Directives
Custom AngularJS DirectivesCustom AngularJS Directives
Custom AngularJS Directives
yprodev
 
Angular Presentation
Angular PresentationAngular Presentation
Angular Presentation
Adam Moore
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
Ben Lin
 
Introduction to AngularJS For WordPress Developers
Introduction to AngularJS For WordPress DevelopersIntroduction to AngularJS For WordPress Developers
Introduction to AngularJS For WordPress Developers
Caldera Labs
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
Juliana Lucena
 
angularJs Workshop
angularJs WorkshopangularJs Workshop
angularJs Workshop
Ran Wahle
 
"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović
JS Belgrade
 
Extend GraphQL with directives
Extend GraphQL with directivesExtend GraphQL with directives
Extend GraphQL with directives
Greg Bergé
 
AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014
Ran Wahle
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
Daniel Bryant
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For Managers
AgileThought
 
Ad

More from Fwdays (20)

Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...
Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...
Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...
Fwdays
 
"Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her...
"Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her..."Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her...
"Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her...
Fwdays
 
"Rebranding for Growth", Anna Velykoivanenko
"Rebranding for Growth", Anna Velykoivanenko"Rebranding for Growth", Anna Velykoivanenko
"Rebranding for Growth", Anna Velykoivanenko
Fwdays
 
"Must-have AI-tools for cost-efficient marketing", Irina Smirnova
"Must-have AI-tools for cost-efficient marketing",  Irina Smirnova"Must-have AI-tools for cost-efficient marketing",  Irina Smirnova
"Must-have AI-tools for cost-efficient marketing", Irina Smirnova
Fwdays
 
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5..."Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
Fwdays
 
"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy
"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy
"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy
Fwdays
 
"Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies", V...
"Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies",  V..."Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies",  V...
"Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies", V...
Fwdays
 
"Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka...
"Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka..."Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka...
"Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka...
Fwdays
 
Performance Marketing Research для запуску нового WorldWide продукту
Performance Marketing Research для запуску нового WorldWide продуктуPerformance Marketing Research для запуску нового WorldWide продукту
Performance Marketing Research для запуску нового WorldWide продукту
Fwdays
 
"Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu...
"Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu..."Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu...
"Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu...
Fwdays
 
"AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea...
"AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea..."AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea...
"AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea...
Fwdays
 
"Constructive Interaction During Emotional Burnout: With Local and Internatio...
"Constructive Interaction During Emotional Burnout: With Local and Internatio..."Constructive Interaction During Emotional Burnout: With Local and Internatio...
"Constructive Interaction During Emotional Burnout: With Local and Internatio...
Fwdays
 
"Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil...
"Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil..."Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil...
"Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil...
Fwdays
 
"39 offers for my mentees in a year. How to create a professional environment...
"39 offers for my mentees in a year. How to create a professional environment..."39 offers for my mentees in a year. How to create a professional environment...
"39 offers for my mentees in a year. How to create a professional environment...
Fwdays
 
"From “doing tasks” to leadership: how to adapt management style to the conte...
"From “doing tasks” to leadership: how to adapt management style to the conte..."From “doing tasks” to leadership: how to adapt management style to the conte...
"From “doing tasks” to leadership: how to adapt management style to the conte...
Fwdays
 
[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...
[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...
[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...
Fwdays
 
[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...
[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...
[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...
Fwdays
 
[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...
[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...
[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...
Fwdays
 
"Dialogue about fakapas: how to pass an interview without unnecessary mistake...
"Dialogue about fakapas: how to pass an interview without unnecessary mistake..."Dialogue about fakapas: how to pass an interview without unnecessary mistake...
"Dialogue about fakapas: how to pass an interview without unnecessary mistake...
Fwdays
 
"Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest...
"Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest..."Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest...
"Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest...
Fwdays
 
Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...
Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...
Від KPI до OKR: як синхронізувати продажі, маркетинг і продукт, щоб бізнес ре...
Fwdays
 
"Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her...
"Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her..."Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her...
"Demand Generation: How a Founder’s Brand Turns Content into Leads", Alex Her...
Fwdays
 
"Rebranding for Growth", Anna Velykoivanenko
"Rebranding for Growth", Anna Velykoivanenko"Rebranding for Growth", Anna Velykoivanenko
"Rebranding for Growth", Anna Velykoivanenko
Fwdays
 
"Must-have AI-tools for cost-efficient marketing", Irina Smirnova
"Must-have AI-tools for cost-efficient marketing",  Irina Smirnova"Must-have AI-tools for cost-efficient marketing",  Irina Smirnova
"Must-have AI-tools for cost-efficient marketing", Irina Smirnova
Fwdays
 
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5..."Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
Fwdays
 
"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy
"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy
"Building a Product IT Team in a Defense-Tech Company", Arthur Seletskiy
Fwdays
 
"Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies", V...
"Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies",  V..."Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies",  V...
"Scaling Smart: GTM Strategies that Fuel Growth for Service IT Companies", V...
Fwdays
 
"Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka...
"Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka..."Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka...
"Pushy Sales Don’t Work: How to Sell Without Driving People Crazy", Aliona Ka...
Fwdays
 
Performance Marketing Research для запуску нового WorldWide продукту
Performance Marketing Research для запуску нового WorldWide продуктуPerformance Marketing Research для запуску нового WorldWide продукту
Performance Marketing Research для запуску нового WorldWide продукту
Fwdays
 
"Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu...
"Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu..."Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu...
"Scaling Product Mindset: From Individual Ideas to Team Culture", Oksana Holu...
Fwdays
 
"AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea...
"AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea..."AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea...
"AI-Driven Automation for High-Performing Teams: Optimize Routine Tasks & Lea...
Fwdays
 
"Constructive Interaction During Emotional Burnout: With Local and Internatio...
"Constructive Interaction During Emotional Burnout: With Local and Internatio..."Constructive Interaction During Emotional Burnout: With Local and Internatio...
"Constructive Interaction During Emotional Burnout: With Local and Internatio...
Fwdays
 
"Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil...
"Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil..."Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil...
"Perfectionisin: What Does the Medicine for Perfectionism Look Like?", Manoil...
Fwdays
 
"39 offers for my mentees in a year. How to create a professional environment...
"39 offers for my mentees in a year. How to create a professional environment..."39 offers for my mentees in a year. How to create a professional environment...
"39 offers for my mentees in a year. How to create a professional environment...
Fwdays
 
"From “doing tasks” to leadership: how to adapt management style to the conte...
"From “doing tasks” to leadership: how to adapt management style to the conte..."From “doing tasks” to leadership: how to adapt management style to the conte...
"From “doing tasks” to leadership: how to adapt management style to the conte...
Fwdays
 
[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...
[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...
[QUICK TALK] "Why Some Teams Grow Better Under Pressure", Oleksandr Marchenko...
Fwdays
 
[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...
[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...
[QUICK TALK] "How to study to acquire a skill, not a certificate?", Uliana Du...
Fwdays
 
[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...
[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...
[QUICK TALK] "Coaching 101: How to Identify and Develop Your Leadership Quali...
Fwdays
 
"Dialogue about fakapas: how to pass an interview without unnecessary mistake...
"Dialogue about fakapas: how to pass an interview without unnecessary mistake..."Dialogue about fakapas: how to pass an interview without unnecessary mistake...
"Dialogue about fakapas: how to pass an interview without unnecessary mistake...
Fwdays
 
"Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest...
"Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest..."Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest...
"Conflicts within a Team: Not an Enemy, But an Opportunity for Growth", Orest...
Fwdays
 

Recently uploaded (20)

HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?
Daniel Lehner
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In FranceManifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
chb3
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?
Daniel Lehner
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In FranceManifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
chb3
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 

"Inside The AngularJS Directive Compiler" by Tero Parviainen

  • 1. Inside The AngularJS Directive Compiler Tero Parviainen @teropa
  • 2. Directives “Angular attempts to minimize the impedance mismatch between document centric HTML and what an application needs by creating new HTML constructs. Angular teaches the browser new syntax through a construct we call directives.” https://docs.angularjs.org/guide/introduction
  • 4. { priority: 0, terminal: false, template: '<div></div>', templateNamespace: 'html', replace: false, multiElement: false, transclude: false, restrict: 'A', scope: false, controller: 'MyCtrl', controllerAs: 'myCtrl', bindToController: true, require: '^parentCtrl', compile: function(el) { return { pre: function(scope, el, attrs) { }, post: function(scope, el, attrs) { } } } }
  • 5. src/ng/compile.js •  1307 lines of code •  84 functions •  Compilation & linking •  Attribute management •  Controllers •  Isolate bindings •  Templates & transclusion https://github.com/es-analysis/plato
  • 7. 1.  Compilation 2.  Linking 3.  Inheritance 4.  Isolation
  • 8. 1.  Compilation 2.  Linking 3.  Inheritance 4.  Isolation
  • 10. $compileProvider.directive('myClass', function() { return { compile: function(element) { element.addClass('decorated'); } }; }); Directive Registration
  • 12. var root = document.querySelector('#root'); var $root = angular.element(root); $compile($root); Compilation
  • 13. The Compile Provider function $CompileProvider() { this.directive = function(name, factory) { }; }
  • 14. Directive Registration function $CompileProvider() { var directives = {}; this.directive = function(name, factory) { directives[name] = directives[name] || []; directives[name].push(factory()); }; }
  • 15. Constructing $compile function $CompileProvider() { var directives = {}; this.directive = function(name, factory) { directives[name] = directives[name] || []; directives[name].push(factory()); }; this.$get = function() { return function $compile(element) { }; }; }
  • 16. The compileNode helper function this.$get = function() { function compileNode(element) { } return function $compile(element) { compileNode(element); }; };
  • 17. Collecting Directives this.$get = function() { function collectDirectives(element) { } function compileNode(element) { var directives = collectDirectives(element); } return function $compile(element) { compileNode(element); }; };
  • 18. Three Collection Strategies this.$get = function() { function collectDirectives(element) { return collectElementDirectives(element) .concat(collectAttrDirectives(element)) .concat(collectClassDirectives(element)); } function compileNode(element) { var directives = collectDirectives(element); } return function $compile(element) { compileNode(element); }; };
  • 19. Element Directives function collectElementDirectives(element) { var elName = element[0].nodeName; var directiveName = _.camelCase(elName); return directives[directiveName] || []; }
  • 20. Attribute Directives function collectAttrDirectives(element) { var result = []; _.each(element[0].attributes, function(attr) { var dirName = _.camelCase(attr.name); result = result.concat(directives[dirName] || []); }); return result; }
  • 21. Class Directives function collectClassDirectives(element) { var result = []; _.each(element[0].classList, function(cName) { var dirName = _.camelCase(cName); result = result.concat(directives[dirName] || []); }); return result; }
  • 22. Applying The Directives function compileNode(element) { var directives = collectDirectives(element); directives.forEach(function(directive) { directive.compile(element); }); }
  • 23. Recursing to Child Nodes function compileNode(element) { var directives = collectDirectives(element); directives.forEach(function(directive) { directive.compile(element); }); element.children().forEach(compileNode); }
  • 24. 1.  Compilation 2.  Linking 3.  Inheritance 4.  Isolation
  • 25. Scopes • Application data + behavior • Change detection • Events
  • 26. The Directive Compiler And Linker $compile Directives + DOM Compiled DOM + Linker Linker Linked DOM Compiled DOM + Scope
  • 27. $compileProvider.directive('myClass', function() { return { compile: function(element) { return function link(scope, element) { element.addClass(scope.theClass); }; } }; }); Directive with a Link Function
  • 28. var root = document.querySelector('#root'); var $root = angular.element(root); var linkFunction = $compile($root); $rootScope.theClass = 'decorated'; linkFunction($rootScope); Linking
  • 29. The Node Link Function function compileNode(element) { var directives = collectDirectives(element); directives.forEach(function(directive) { directive.compile(element); }); element.children().forEach(compileNode); return function nodeLinkFn(scope) { }; } return function $compile(element) { return compileNode(element); };
  • 30. Collect Link Functions function compileNode(element) { var directives = collectDirectives(element), linkFns = []; directives.forEach(function(directive) { var linkFn = directive.compile(element); linkFns.push(linkFn); }); element.children().forEach(compileNode); return function nodeLinkFn(scope) { }; }
  • 31. Apply Link Functions function compileNode(element) { var directives = collectDirectives(element), linkFns = []; directives.forEach(function(directive) { var linkFn = directive.compile(element); linkFns.push(linkFn); }); element.children().forEach(compileNode); return function nodeLinkFn(scope) { linkFns.forEach(function(linkFn) { linkFn(scope, element); }); }; }
  • 32. Collect Child Link Functions function compileNode(element) { var directives = collectDirectives(element), linkFns = []; directives.forEach(function(directive) { var linkFn = directive.compile(element); linkFns.push(linkFn); }); var childLinkFns = element.children().map(compileNode); return function nodeLinkFn(scope) { linkFns.forEach(function(linkFn) { linkFn(scope, element); }); }; }
  • 33. Apply Child Link Functions function compileNode(element) { var directives = collectDirectives(element), linkFns = []; directives.forEach(function(directive) { var linkFn = directive.compile(element); linkFns.push(linkFn); }); var childLinkFns = element.children().map(compileNode); return function nodeLinkFn(scope) { childLinkFns.forEach(function(childLinkFn) { childLinkFn(scope); }); linkFns.forEach(function(linkFn) { linkFn(scope, element); }); }; }
  • 34. 1.  Compilation 2.  Linking 3.  Inheritance 4.  Isolation
  • 36. Scope Hierarchy vs. DOM Hierarchy <article ng-app="myApp"> <section ng-controller="..."></section> <section ng-controller="..."> <div ng-controller="..."> </div> </section> </article> $rootScope $scope $scope $scope article section section div
  • 37. $compileProvider.directive('myClass', function() { return { scope: true, compile: function(element) { return function link(scope, element) { scope.counter = 0; element.on('click', function() { scope.counter++; }); }; } }; }); Directive Requests a Scope
  • 38. Remember The “New Scope Directive” function compileNode(element) { var directives = collectDirectives(element), linkFns = [], newScopeDir; directives.forEach(function(directive) { var linkFn = directive.compile(element); linkFns.push(linkFn); if (directive.scope) { if (newScopeDir) { throw 'No more than 1 new scope plz!'; } newScopeDir = directive; } }); // ... }
  • 39. Make a new scope during linking return function nodeLinkFn(scope) { if (newScopeDir) { scope = scope.$new(); } childLinkFns.forEach(function(childLinkFn) { childLinkFn(scope); }); linkFns.forEach(function(linkFn) { linkFn(scope, element); }); };
  • 40. 1.  Compilation 2.  Linking 3.  Inheritance 4.  Isolation
  • 43. Directive with Isolate Scope & Bindings <div click-logger="'Hello!'"></div> $compileProvider.directive('clickLogger', function() { return { scope: { message: '=clickLogger' }, compile: function(element) { return function link(scope, element) { scope.counter = 0; element.on('click', function() { console.log(scope.message); }); }; } }; });
  • 44. Remember The “Iso Scope Directive” function compileNode(element) { var directives = collectDirectives(element), linkFns = [], newScopeDir, newIsoScopeDir; directives.forEach(function(directive) { var linkFn = directive.compile(element); linkFns.push(linkFn); if (directive.scope) { if (newScopeDir || newIsoScopeDir) { throw 'No more than 1 new scope plz!'; } if (_.isObject(directive.scope)) { newIsoScopeDir = directive; } else { newScopeDir = directive; } } }); // ... }
  • 45. Create Isolate Scope During Linking return function nodeLinkFn(scope) { var isoScope; if (newScopeDir) { scope = scope.$new(); } if (newIsoScopeDir) { isoScope = scope.$new(true); } childLinkFns.forEach(function(childLinkFn) { childLinkFn(scope); }); linkFns.forEach(function(linkFn) { linkFn(scope, element); }); };
  • 46. Remember Link Function Directives function compileNode(element) { var directives = collectDirectives(element), linkFns = [], newScopeDir, newIsoScopeDir; directives.forEach(function(directive) { var linkFn = directive.compile(element); linkFn.directive = directive; linkFns.push(linkFn); if (directive.scope) { if (newScopeDir || newIsoScopeDir) { throw 'No more than 1 new scope plz!'; } if (_.isObject(directive.scope)) { newIsoScopeDir = directive; } else { newScopeDir = directive; } } }); // ...
  • 47. Apply Isolate Scope return function nodeLinkFn(scope) { var isoScope; if (newScopeDir) { scope = scope.$new(); } if (newIsoScopeDir) { isoScope = scope.$new(true); } childLinkFns.forEach(function(childLinkFn) { childLinkFn(scope); }); linkFns.forEach(function(linkFn) { var isIso = (linkFn.directive === newIsoScopeDir); linkFn(isIso ? isoScope : scope, element); }); };
  • 48. Isolate Bindings <div click-logger="'Hello!'"></div> $compileProvider.directive('clickLogger', function() { return { scope: { message: '=clickLogger' }, compile: function(element) { return function link(scope, element) { scope.counter = 0; element.on('click', function() { console.log(scope.message); }); }; } }; });
  • 49. Loop Over Isolate Bindings return function nodeLinkFn(scope) { var isoScope; if (newScopeDir) { scope = scope.$new(); } if (newIsoScopeDir) { isoScope = scope.$new(true); _.forOwn( newIsoScopeDir.scope, function(spec, scopeName) { } ); } // ... };
  • 50. Get Attribute Expression if (newIsoScopeDir) { isoScope = scope.$new(true); _.forOwn( newIsoScopeDir.scope, function(spec, scopeName) { var attrName = spec.match(/^=(.*)/)[1]; var denormalized = _.kebabCase(attrName); var expr = element.attr(denormalized); } ); }
  • 51. Watch & Bind The Expression if (newIsoScopeDir) { isoScope = scope.$new(true); _.forOwn( newIsoScopeDir.scope, function(spec, scopeName) { var attrName = spec.match(/^=(.*)/)[1]; var denormalized = _.kebabCase(attrName); var expr = element.attr(denormalized); scope.$watch(expr, function(newValue) { isoScope[scopeName] = newValue; }); } ); }
  • 52. Two-Way Data Binding $rootScope $scope $scope $scope expression attribute Two directions
  • 53. Parse Expression String to Function if (newIsoScopeDir) { isoScope = scope.$new(true); _.forOwn( newIsoScopeDir.scope, function(spec, scopeName) { var attrName = spec.match(/^=(.*)/)[1]; var denormalized = _.kebabCase(attrName); var expr = element.attr(denormalized); var exprFn = $parse(expr); scope.$watch(exprFn, function(newValue) { isoScope[scopeName] = newValue; }); } ); }
  • 54. Refactor The Watcher if (newIsoScopeDir) { isoScope = scope.$new(true); _.forOwn( newIsoScopeDir.scope, function(spec, scopeName) { var attrName = spec.match(/^=(.*)/)[1]; var denormalized = _.kebabCase(attrName); var expr = element.attr(denormalized); var exprFn = $parse(expr); scope.$watch(function() { var newParentValue = exprFn(scope); var childValue = isoScope[scopeName]; if (newParentValue !== childValue) { isoScope[scopeName] = newParentValue; } }); } ); }
  • 55. Track The Parent Value _.forOwn( newIsoScopeDir.scope, function(spec, scopeName) { var attrName = spec.match(/^=(.*)/)[1]; var denormalized = _.kebabCase(attrName); var expr = element.attr(denormalized); var exprFn = $parse(expr); var parentValue; scope.$watch(function() { var newParentValue = exprFn(scope); var childValue = isoScope[scopeName]; if (newParentValue !== childValue) { isoScope[scopeName] = newParentValue; } parentValue = newParentValue; }); } );
  • 56. Check for Parent vs. Child Change var parentValue; scope.$watch(function() { var newParentValue = exprFn(scope); var childValue = isoScope[scopeName]; if (newParentValue !== childValue) { if (newParentValue !== parentValue) { isoScope[scopeName] = newParentValue; } else { } } parentValue = newParentValue; });
  • 57. Propagate Change Up var parentValue; scope.$watch(function() { var newParentValue = exprFn(scope); var childValue = isoScope[scopeName]; if (newParentValue !== childValue) { if (newParentValue !== parentValue) { isoScope[scopeName] = newParentValue; } else { exprFn.assign(scope, childValue); newParentValue = childValue; } } parentValue = newParentValue; });
  • 58. 1.  Compilation 2.  Linking 3.  Inheritance 4.  Isolation
  • 59. teropa.info -75% off list price with code ”FRAMEWORKSDAYS”