Slide 1

Slide 1 text

Radoslav Stankov 27/08/2014

Slide 2

Slide 2 text

Radoslav Stankov @rstankov ! ! ! ! http://rstankov.com

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

https://speakerdeck.com/rstankov/angular-tips-and-tricks

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

credits: http://www.bennadel.com/

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Dependency Injection

Slide 11

Slide 11 text

app = angular.module('Demo', []);

Slide 12

Slide 12 text

app = angular.module('Demo', []);

Slide 13

Slide 13 text

app = angular.module('Demo', []);

Slide 14

Slide 14 text

app.value('Porduct', { title: 'iPhone', price: 700 });

Slide 15

Slide 15 text

app.value('Porduct', { title: 'iPhone', price: 700 });

Slide 16

Slide 16 text

app.value('Porduct', { title: 'iPhone', price: 700 });

Slide 17

Slide 17 text

app.value('Porduct', { title: 'iPhone', price: 700 });

Slide 18

Slide 18 text

app.value('Porduct', { title: 'iPhone', price: 700 });

Slide 19

Slide 19 text

app.controller(function($scope, Product){ $scope.product = Product; });

Slide 20

Slide 20 text

app.controller(function($scope, Product){ $scope.product = Product; });

Slide 21

Slide 21 text

app.controller(function($scope, Product){ $scope.product = Product; });

Slide 22

Slide 22 text

app.controller(function($scope, Product){ $scope.product = Product; });

Slide 23

Slide 23 text

app.controller(function($scope, Product){ $scope.product = Product; });

Slide 24

Slide 24 text

app.controller(function($scope, Product){ $scope.product = Product; });

Slide 25

Slide 25 text

app.controller(function($scope, Product){ $scope.product = Product; });

Slide 26

Slide 26 text

app.controller(function($scope, Product){ $scope.product = Product; });

Slide 27

Slide 27 text

app.controller(function($scope, Product){ $scope.product = Product; });

Slide 28

Slide 28 text

Error: [$injector:unpr] 
 Unknown provider: ProductProvider <- Product

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

app.value('Porduct', { title: 'iPhone', price: 700 });

Slide 31

Slide 31 text

app.value('Porduct', { title: 'iPhone', price: 700 });

Slide 32

Slide 32 text

app.value('Porduct', { title: 'iPhone', price: 700 });

Slide 33

Slide 33 text

app.value('Product', { title: 'iPhone', price: 700 });

Slide 34

Slide 34 text

Error: [$injector:unpr] 
 Unknown provider: ProductProvider <- Product

Slide 35

Slide 35 text

Error: [$injector:unpr] 
 Unknown provider: ProductProvider <- Product

Slide 36

Slide 36 text

Error: [$injector:unpr] 
 Unknown provider: ProductProvider <- Product

Slide 37

Slide 37 text

Error: [$injector:unpr] 
 Unknown provider: ProductProvider <- Product

Slide 38

Slide 38 text

Error: [$injector:unpr] 
 Unknown provider: ProductProvider <- Product

Slide 39

Slide 39 text

Error: [$injector:unpr] 
 Unknown provider: ProductProvider <- Product

Slide 40

Slide 40 text

Error: [$injector:unpr] 
 Unknown provider: ProductProvider <- Product

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

value service factory provider injector.get(‘Person’) Person

Slide 43

Slide 43 text

app.value('Person', { name: 'Rado', });

Slide 44

Slide 44 text

app.value('Person', { name: 'Rado', });

Slide 45

Slide 45 text

app.value('Person', { name: 'Rado', });

Slide 46

Slide 46 text

app.value('Person', { name: 'Rado', });

Slide 47

Slide 47 text

app.value('Person', { name: 'Rado', });

Slide 48

Slide 48 text

app.controller(function($scope, Person, $window) { $window.alert(Person.name + ' - hi'); });

Slide 49

Slide 49 text

app.controller(function($scope, Person, $window) { $window.alert(Person.name + ' - hi'); });

Slide 50

Slide 50 text

app.controller(function($scope, Person, $window) { $window.alert(Person.name + ' - hi'); });

Slide 51

Slide 51 text

app.controller(function($scope, Person, $window) { $window.alert(Person.name + ' - hi'); });

Slide 52

Slide 52 text

app.controller(function($scope, Person, $window) { $window.alert(Person.name + ' - hi'); });

Slide 53

Slide 53 text

injector.get(‘Person’) Person

Slide 54

Slide 54 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 55

Slide 55 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 56

Slide 56 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 57

Slide 57 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 58

Slide 58 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 59

Slide 59 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 60

Slide 60 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 61

Slide 61 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 62

Slide 62 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 63

Slide 63 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 64

Slide 64 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 65

Slide 65 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 66

Slide 66 text

app.factory('Person', function($window) { var name = ''; ! return { setName: function(newName) { name = newName; }, getName: function() { return name; }, say: function(text) { $window.alert(name + ' - ' + text); } } });

Slide 67

Slide 67 text

app.controller(function($scope, Person) { Person.setName('Radoslav Stankov'); Person.say('Hi'); });

Slide 68

Slide 68 text

app.controller(function($scope, Person) { Person.setName('Radoslav Stankov'); Person.say('Hi'); });

Slide 69

Slide 69 text

app.controller(function($scope, Person) { Person.setName('Radoslav Stankov'); Person.say('Hi'); });

Slide 70

Slide 70 text

app.controller(function($scope, Person) { Person.setName('Radoslav Stankov'); Person.say('Hi'); });

Slide 71

Slide 71 text

app.controller(function($scope, Person) { Person.setName('Radoslav Stankov'); Person.say('Hi'); });

Slide 72

Slide 72 text

Cache? Cache = factory(…) false true injector.get(‘Person’) Person

Slide 73

Slide 73 text

app.service('Person', function($window) { var name = ''; ! this.setName = function(newName) { name = newName; }; ! this.getName = function() { return name; }; ! this.say = function(text) { $window.alert(name + ' - ' + text); }; });

Slide 74

Slide 74 text

app.service('Person', function($window) { var name = ''; ! this.setName = function(newName) { name = newName; }; ! this.getName = function() { return name; }; ! this.say = function(text) { $window.alert(name + ' - ' + text); }; });

Slide 75

Slide 75 text

app.service('Person', function($window) { var name = ''; ! this.setName = function(newName) { name = newName; }; ! this.getName = function() { return name; }; ! this.say = function(text) { $window.alert(name + ' - ' + text); }; });

Slide 76

Slide 76 text

app.service('Person', function($window) { var name = ''; ! this.setName = function(newName) { name = newName; }; ! this.getName = function() { return name; }; ! this.say = function(text) { $window.alert(name + ' - ' + text); }; });

Slide 77

Slide 77 text

app.service('Person', function($window) { var name = ''; ! this.setName = function(newName) { name = newName; }; ! this.getName = function() { return name; }; ! this.say = function(text) { $window.alert(name + ' - ' + text); }; });

Slide 78

Slide 78 text

app.controller(function($scope, Person) { Person.setName('Radoslav Stankov'); Person.say('Hi'); });

Slide 79

Slide 79 text

Cache? Cache = new service(…) false true injector.get(‘Person’) Person

Slide 80

Slide 80 text

app.provider('Person', function() { this.name = ''; ! this.$get = function($window) { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });

Slide 81

Slide 81 text

app.provider('Person', function() { this.name = ''; ! this.$get = function($window) { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });

Slide 82

Slide 82 text

app.provider('Person', function() { this.name = ''; ! this.$get = function($window) { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });

Slide 83

Slide 83 text

app.provider('Person', function() { this.name = ''; ! this.$get = function($window) { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });

Slide 84

Slide 84 text

app.provider('Person', function() { this.name = ''; ! this.$get = function($window) { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });

Slide 85

Slide 85 text

app.provider('Person', function() { this.name = ''; ! this.$get = function($window) { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });

Slide 86

Slide 86 text

app.provider('Person', function() { this.name = ''; ! this.$get = function($window) { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });

Slide 87

Slide 87 text

app.provider('Person', function() { this.name = ''; ! this.$get = function($window) { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });

Slide 88

Slide 88 text

app.provider('Person', function() { this.name = ''; ! this.$get = function($window) { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });

Slide 89

Slide 89 text

app.provider('Person', function() { this.name = ''; ! this.$get = function($window) { var self = this; return { setName: function(newName) { self.name = newName; }, getName: function() { return self.name; }, say: function(text) { $window.alert(self.name + ' - ' + text); } }; } });

Slide 90

Slide 90 text

app.config(function(PersonProvider){ PersonProvider.name = 'Rado'; });

Slide 91

Slide 91 text

app.config(function(PersonProvider){ PersonProvider.name = 'Rado'; });

Slide 92

Slide 92 text

app.config(function(PersonProvider){ PersonProvider.name = 'Rado'; });

Slide 93

Slide 93 text

app.config(function(PersonProvider){ PersonProvider.name = 'Rado'; });

Slide 94

Slide 94 text

app.config(function(PersonProvider){ PersonProvider.name = 'Rado'; });

Slide 95

Slide 95 text

app.config(function(PersonProvider){ PersonProvider.name = 'Rado'; });

Slide 96

Slide 96 text

app.config(function(PersonProvider){ PersonProvider.name = 'Rado'; });

Slide 97

Slide 97 text

app.controller(function($scope, Person) { Person.say('Hi'); });

Slide 98

Slide 98 text

app.controller(function($scope, Person) { Person.say('Hi'); });

Slide 99

Slide 99 text

app.controller(function($scope, Person) { Person.say('Hi'); });

Slide 100

Slide 100 text

Cache? Cache = new provider(…) false true injector.get(‘PersonProvider’) PersonProvider

Slide 101

Slide 101 text

Cache? false true injector.get(‘Person’) Person injector.get(‘PersonProvider’) Cache = PersonProvider.$get(…)

Slide 102

Slide 102 text

Error: [$injector:unpr] 
 Unknown provider: ProductProvider <- Product

Slide 103

Slide 103 text

No content

Slide 104

Slide 104 text

No content

Slide 105

Slide 105 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function value(name, val) { return factory(name, valueFn(val)); }

Slide 106

Slide 106 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function value(name, val) { return factory(name, valueFn(val)); }

Slide 107

Slide 107 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function value(name, val) { return factory(name, valueFn(val)); }

Slide 108

Slide 108 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function value(name, val) { return factory(name, valueFn(val)); }

Slide 109

Slide 109 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function value(name, val) { return factory(name, valueFn(val)); }

Slide 110

Slide 110 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function value(name, val) { return factory(name, valueFn(val)); }

Slide 111

Slide 111 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function value(name, val) { return factory(name, valueFn(val)); }

Slide 112

Slide 112 text

function factory(name, factoryFn) { return provider(name, {$get: factoryFn}); } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 113

Slide 113 text

function factory(name, factoryFn) { return provider(name, {$get: factoryFn}); } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 114

Slide 114 text

function factory(name, factoryFn) { return provider(name, {$get: factoryFn}); } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 115

Slide 115 text

function factory(name, factoryFn) { return provider(name, {$get: factoryFn}); } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 116

Slide 116 text

function factory(name, factoryFn) { return provider(name, {$get: factoryFn}); } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 117

Slide 117 text

function factory(name, factoryFn) { return provider(name, {$get: factoryFn}); } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 118

Slide 118 text

function factory(name, factoryFn) { return provider(name, {$get: factoryFn}); } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 119

Slide 119 text

Error: [$injector:unpr] 
 Unknown provider: ProductProvider <- Product

Slide 120

Slide 120 text

Cache? false true injector.get(‘Person’) Person injector.get(‘PersonProvider’) Cache = PersonProvider.$get(…)

Slide 121

Slide 121 text

No content

Slide 122

Slide 122 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 123

Slide 123 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 124

Slide 124 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 125

Slide 125 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 126

Slide 126 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 127

Slide 127 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 128

Slide 128 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 129

Slide 129 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 130

Slide 130 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 131

Slide 131 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 132

Slide 132 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 133

Slide 133 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 134

Slide 134 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 135

Slide 135 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); }

Slide 136

Slide 136 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); }

Slide 137

Slide 137 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); }

Slide 138

Slide 138 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); }

Slide 139

Slide 139 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); }

Slide 140

Slide 140 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); }

Slide 141

Slide 141 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); }

Slide 142

Slide 142 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 143

Slide 143 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 144

Slide 144 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); ! if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } ! if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get fac } ! return providerCache[name + providerSuffix] = provider_; }

Slide 145

Slide 145 text

function instantiate(Type, locals, serviceName) { var Constructor = function() {}; Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 146

Slide 146 text

function instantiate(Type, locals, serviceName) { var Constructor = function() {}; Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 147

Slide 147 text

function instantiate(Type, locals, serviceName) { var Constructor = function() {}; Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 148

Slide 148 text

function instantiate(Type, locals, serviceName) { var Constructor = function() {}; Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 149

Slide 149 text

function instantiate(Type, locals, serviceName) { var Constructor = function() {}; Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 150

Slide 150 text

function instantiate(Type, locals, serviceName) { var Constructor = function() {}; Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 151

Slide 151 text

function instantiate(Type, locals, serviceName) { var Constructor = function() {}; Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Typ var instance = new Constructor(); var returnedValue = invoke(Type, instance, locals, serviceName); ! if (isObject(returnedValue) || isFunction(returnedValue)) { return returnedValue; } else { return instance; } } https://github.com/angular/angular.js/blob/master/src/auto/injector.js

Slide 152

Slide 152 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 153

Slide 153 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 154

Slide 154 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 155

Slide 155 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 156

Slide 156 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 157

Slide 157 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 158

Slide 158 text

app.factory('MyFactory', function(Dependancy1, Dependancy2) { /* code */ });

Slide 159

Slide 159 text

app.factory('MyFactory', ['Dependancy1', 'Dependancy2', function(Dependancy1, Dependancy2) { /* code */ } ]);

Slide 160

Slide 160 text

function MyFactory(Dependancy1, Dependancy2) { /* code */ } ! MyFactory.$inject = ['Dependancy1', 'Dependancy2'] ! app.factory('MyFactory', MyFactory);

Slide 161

Slide 161 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 162

Slide 162 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 163

Slide 163 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 164

Slide 164 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 165

Slide 165 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 166

Slide 166 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 167

Slide 167 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 168

Slide 168 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 169

Slide 169 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 170

Slide 170 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 171

Slide 171 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 172

Slide 172 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 173

Slide 173 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 174

Slide 174 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 175

Slide 175 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 176

Slide 176 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 177

Slide 177 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 178

Slide 178 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 179

Slide 179 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 180

Slide 180 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 181

Slide 181 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 182

Slide 182 text

function annotate(fn, strictDi, name) { var $inject; ! if (typeof fn === 'function') { if (!($inject = fn.$inject)) { // ... fill inject from argument names } } else if (isArray(fn)) { var last = fn.length - 1; assertArgFn(fn[last], 'fn'); $inject = fn.slice(0, last); } else { assertArgFn(fn, 'fn', true); } return $inject; } https://github.com/angular/angular.js/blob/master/src/auto/injector.js*

Slide 183

Slide 183 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 184

Slide 184 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 185

Slide 185 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js* function invoke(fn, self, locals, serviceName) { var args = [], $inject = annotate(fn, strictDi, serviceName); ! for(var i = 0, length = $inject.length; i < length; i++) { var key = $inject[i]; if (typeof key !== 'string') { throw $injectorMinErr('...'); } args.push(getService(key)); } ! return fn.apply(self, args); }

Slide 186

Slide 186 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code } else { // ... code } }

Slide 187

Slide 187 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] === INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }

Slide 188

Slide 188 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] === INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }

Slide 189

Slide 189 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] === INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }

Slide 190

Slide 190 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] === INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }

Slide 191

Slide 191 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] === INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }

Slide 192

Slide 192 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] === INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }

Slide 193

Slide 193 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { if (cache[serviceName] === INSTANTIATING) { throw $injectorMinErr('cdep', 'Circular dependency found: {0}', serviceName + ' <- ' + path.join(' <- ')); } return cache[serviceName]; } else { // ... code } }

Slide 194

Slide 194 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }

Slide 195

Slide 195 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }

Slide 196

Slide 196 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }

Slide 197

Slide 197 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }

Slide 198

Slide 198 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }

Slide 199

Slide 199 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }

Slide 200

Slide 200 text

https://github.com/angular/angular.js/blob/master/src/auto/injector.js function getService(serviceName) { if (cache.hasOwnProperty(serviceName)) { // ... code } else { try { path.unshift(serviceName); cache[serviceName] = INSTANTIATING; return cache[serviceName] = factory(serviceName); } catch (err) { if (cache[serviceName] === INSTANTIATING) { delete cache[serviceName]; } throw err; } finally { path.shift(); } } }

Slide 201

Slide 201 text

Error: [$injector:unpr] 
 Unknown provider: ProductProvider <- Product

Slide 202

Slide 202 text

No content

Slide 203

Slide 203 text

angular.injector(['Demo']).invoke(function(Product) { /* code */ });

Slide 204

Slide 204 text

Uncaught Error: [$injector:unpr] Unknown provider: ! $rootElementProvider <- $rootElement <- $location <- $http <- $resource <- Product

Slide 205

Slide 205 text

Uncaught Error: [$injector:unpr] Unknown provider: ! $rootElementProvider <- $rootElement <- $location <- $http <- $resource <- Product

Slide 206

Slide 206 text

Uncaught Error: [$injector:unpr] Unknown provider: ! $rootElementProvider <- $rootElement <- $location <- $http <- $resource <- Product

Slide 207

Slide 207 text

No content

Slide 208

Slide 208 text

https://docs.angularjs.org/guide/bootstrap

Slide 209

Slide 209 text

https://github.com/angular/angular.js/blob/master/src/Angular.js function bootstrap(element, modules, config) { // ... setup ! var doBootstrap = function() { // ... do bootstrapping }; ! // ... call doBootstrap }

Slide 210

Slide 210 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 211

Slide 211 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 212

Slide 212 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 213

Slide 213 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 214

Slide 214 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 215

Slide 215 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 216

Slide 216 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 217

Slide 217 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 218

Slide 218 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 219

Slide 219 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 220

Slide 220 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 221

Slide 221 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 222

Slide 222 text

https://github.com/angular/angular.js/blob/master/src/Angular.js var doBootstrap = function() { element = jqLite(element); ! // ... ! modules.unshift(['$provide', function($provide) { $provide.value('$rootElement', element); }]); modules.unshift('ng'); var injector = createInjector(modules, config.strictDi); injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector function bootstrapApply(scope, element, compile, injector) { scope.$apply(function() { element.data('$injector', injector); compile(element)(scope); }); }] ); return injector; };

Slide 223

Slide 223 text

angular.element( document.querySelector(‘[ng-app]’) ).data(‘injector').invoke(function(Product){ /* code */ });

Slide 224

Slide 224 text

angular.element( document.querySelector(‘[ng-app]’) ).injector().invoke(function(Product){ /* code */ });

Slide 225

Slide 225 text

No content

Slide 226

Slide 226 text

// development.js app.invoke = function(fn) { var dom = document.querySelector('[ng-app="' + this.name + '"]'), element = angular.element(dom); ! return element.injector().invoke(fn); } 1

Slide 227

Slide 227 text

! app.invoke(function(Product) { /* code */ });

Slide 228

Slide 228 text

ngMock

Slide 229

Slide 229 text

Angular 2.0 (ES6+)

Slide 230

Slide 230 text

No content

Slide 231

Slide 231 text

Tips and Tricks

Slide 232

Slide 232 text

ngRouter

Slide 233

Slide 233 text

ngRouter

Slide 234

Slide 234 text

ngRouter

Slide 235

Slide 235 text

uiRouter

Slide 236

Slide 236 text

uiRouter https://github.com/angular-ui/ui-router 2

Slide 237

Slide 237 text

app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl: ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });

Slide 238

Slide 238 text

app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl: ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });

Slide 239

Slide 239 text

app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl: ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });

Slide 240

Slide 240 text

app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl: ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });

Slide 241

Slide 241 text

app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl: ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });

Slide 242

Slide 242 text

app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl: ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });

Slide 243

Slide 243 text

app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl: ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });

Slide 244

Slide 244 text

app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl: ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });

Slide 245

Slide 245 text

app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl: ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });

Slide 246

Slide 246 text

Nested routes https://github.com/angular-ui/ui-router/wiki/Nested-States-&-Nested-Views /settings/ /settings/passwords /settings/invoices/ /settings/invoices/:id /settings/repos/ /settings/repos/new
 /settings/repos/:id

Slide 247

Slide 247 text

Multiple named views https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

Slide 248

Slide 248 text

Multiple named views https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

Slide 249

Slide 249 text

Multiple named views https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

Slide 250

Slide 250 text

Multiple named views https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

Slide 251

Slide 251 text

ui-sref https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref Home | About !

Slide 252

Slide 252 text

ui-sref https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref Home | About !

Slide 253

Slide 253 text

ui-sref https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref Home | About !

Slide 254

Slide 254 text

ui-sref https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref Home | About !

Slide 255

Slide 255 text

ui-sref https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref Home | About !

Slide 256

Slide 256 text

2.0

Slide 257

Slide 257 text

Interceptors

Slide 258

Slide 258 text

app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl: ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });

Slide 259

Slide 259 text

app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl: ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });

Slide 260

Slide 260 text

app.config(function($stateProvider) { $stateProvider .state('product', { url: '/product/:id', controller: ‘productCtrl', templateUrl: ‘product.html', resolve: { product: function($stateParams, Product) { return Product.get(id: $stateParams.id).$promise; } } }); });

Slide 261

Slide 261 text

app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found' }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3

Slide 262

Slide 262 text

app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found' }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3

Slide 263

Slide 263 text

app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found' }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3

Slide 264

Slide 264 text

app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found' }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3

Slide 265

Slide 265 text

app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found' }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3

Slide 266

Slide 266 text

app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found' }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3

Slide 267

Slide 267 text

app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found' }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3

Slide 268

Slide 268 text

app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found' }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3

Slide 269

Slide 269 text

app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found' }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3

Slide 270

Slide 270 text

app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found' }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3

Slide 271

Slide 271 text

app.config(function($httpProvider) { var CODE_MAPPING = { 401: '/errors/unauthorized', 404: ‘/errors/not_found' }; ! $httpProvider.interceptors.push(function($q, $location) { return { 'responseError': function(rejection) { var path = CODE_MAPPING[rejection.status]; if (path) { return $location.path(path); } else { return $q.reject(rejection); } } }; }); }); 3

Slide 272

Slide 272 text

Directives

Slide 273

Slide 273 text

Slide 274

Slide 274 text

4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope, element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });

Slide 275

Slide 275 text

4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope, element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });

Slide 276

Slide 276 text

4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope, element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });

Slide 277

Slide 277 text

4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope, element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });

Slide 278

Slide 278 text

4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope, element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });

Slide 279

Slide 279 text

4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope, element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });

Slide 280

Slide 280 text

4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope, element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });

Slide 281

Slide 281 text

4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope, element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });

Slide 282

Slide 282 text

4 app.directive('simpleFileUpload', function() { return { require: '?ngModel', link: function(scope, element, attrs, ngModel) { return element.on('change', function(event) { return scope.$apply(function() { return ngModel.$setViewValue(event.target.files[0]); }); }); } }; });

Slide 283

Slide 283 text

transclusion

Slide 284

Slide 284 text

Long text

Very long text

Very very long text

Even longer text than the very very long text

Slide 285

Slide 285 text

Long text

Very long text

Very very long text

Even longer text than the very very long text

Slide 286

Slide 286 text

Long text

Very long text

Very very long text

Even longer text than the very very long text

Slide 287

Slide 287 text

Long text

Very long text

Very very long text

Even longer text than the very very long text

Slide 288

Slide 288 text

Long text

Very long text

Very very long text

Even longer text than the very very long text

Slide 289

Slide 289 text

! !
Description

Long text

Very long text

Very very long text

Even longer text than the very very long text

Slide 290

Slide 290 text

! !
Description

Long text

Very long text

Very very long text

Even longer text than the very very long text

Slide 291

Slide 291 text

! !
Description

Long text

Very long text

Very very long text

Even longer text than the very very long text

Slide 292

Slide 292 text

5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true, scope: { title: '=title' }, template: '
' + '
{{title}}
' + '
' + '
' }; });

Slide 293

Slide 293 text

5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true, scope: { title: '=title' }, template: '
' + '
{{title}}
' + '
' + '
' }; });

Slide 294

Slide 294 text

5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true, scope: { title: '=title' }, template: '
' + '
{{title}}
' + '
' + '
' }; });

Slide 295

Slide 295 text

5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true, scope: { title: '=title' }, template: '
' + '
{{title}}
' + '
' + '
' }; });

Slide 296

Slide 296 text

5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true, scope: { title: '=title' }, template: '
' + '
{{title}}
' + '
' + '
' }; });

Slide 297

Slide 297 text

5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true, scope: { title: '=title' }, template: '
' + '
{{title}}
' + '
' + '
' }; });

Slide 298

Slide 298 text

5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true, scope: { title: '=title' }, template: '
' + '
{{title}}
' + '
' + '
' }; });

Slide 299

Slide 299 text

5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true, scope: { title: '=title' }, template: '
' + '
{{title}}
' + '
' + '
' }; });

Slide 300

Slide 300 text

5 app.directive('myPanel', function() { return { restrict: 'E', transclude: true, scope: { title: '=title' }, template: '
' + '
{{title}}
' + '
' + '
' }; });

Slide 301

Slide 301 text

Long text

Very long text

Very very long text

Even longer text than the very very long text

Slide 302

Slide 302 text

! !
Description

Long text

Very long text

Very very long text

Even longer text than the very very long text

Slide 303

Slide 303 text

ng-if vs ng-show/ng-hide 6

Slide 304

Slide 304 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict: 'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];

Slide 305

Slide 305 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict: 'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];

Slide 306

Slide 306 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict: 'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];

Slide 307

Slide 307 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict: 'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];

Slide 308

Slide 308 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict: 'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];

Slide 309

Slide 309 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict: 'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];

Slide 310

Slide 310 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict: 'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];

Slide 311

Slide 311 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict: 'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];

Slide 312

Slide 312 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngShowHide.js var ngShowDirective = ['$animate', function($animate) { return { restrict: 'A', multiElement: true, link: function(scope, element, attr) { scope.$watch(attr.ngShow, function ngShowWatchAction(value){ $animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide') }); } }; }];

Slide 313

Slide 313 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude: 'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];

Slide 314

Slide 314 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude: 'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];

Slide 315

Slide 315 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude: 'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];

Slide 316

Slide 316 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude: 'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];

Slide 317

Slide 317 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude: 'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];

Slide 318

Slide 318 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude: 'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];

Slide 319

Slide 319 text

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js var ngIfDirective = ['$animate', function($animate) { return { transclude: 'element', // ... settings link: function ($scope, $element, $attr, ctrl, $transclude) { $scope.$watch($attr.ngIf, function ngIfWatchAction(value) { if (value) { // add content from page } else { // remove content from page } }); } }; }];

Slide 320

Slide 320 text

https://github.com/Pasvaz/bindonce 7

Slide 321

Slide 321 text

1.3.0

Slide 322

Slide 322 text

!
  • {{::item.name}}
  • https://github.com/angular/angular.js/commit/cee429f0aaebf32ef1c9aedd8447a48f163dd0a4

    Slide 323

    Slide 323 text

    !
  • {{::item.name}}
  • https://github.com/angular/angular.js/commit/cee429f0aaebf32ef1c9aedd8447a48f163dd0a4

    Slide 324

    Slide 324 text

    !
  • {{::item.name}}
  • https://github.com/angular/angular.js/commit/cee429f0aaebf32ef1c9aedd8447a48f163dd0a4

    Slide 325

    Slide 325 text

    !
  • {{::item.name}}
  • https://github.com/angular/angular.js/commit/cee429f0aaebf32ef1c9aedd8447a48f163dd0a4

    Slide 326

    Slide 326 text

    !
  • {{::item.name}}
  • https://github.com/angular/angular.js/commit/cee429f0aaebf32ef1c9aedd8447a48f163dd0a4

    Slide 327

    Slide 327 text

    !
  • {{::item.name}}
  • https://github.com/angular/angular.js/commit/cee429f0aaebf32ef1c9aedd8447a48f163dd0a4

    Slide 328

    Slide 328 text

    !
  • {{::item.name}}
  • https://github.com/angular/angular.js/commit/cee429f0aaebf32ef1c9aedd8447a48f163dd0a4

    Slide 329

    Slide 329 text

    No content

    Slide 330

    Slide 330 text

    https://github.com/RStankov/talk-angular-tips-tricks The code commit by commit

    Slide 331

    Slide 331 text

    И сега на къде? https://angularjs.org/

    Slide 332

    Slide 332 text

    No content

    Slide 333

    Slide 333 text

    No content

    Slide 334

    Slide 334 text

    @rstankov Thank you :)

    Slide 335

    Slide 335 text

    No content