get rid of controllers in angular 1.5.x start using component directives

23
Get rid of controllers in AngularJS 1.5.x Start using component directives Fakiolas Marios - [email protected] / @fakiolinho Frontend Developer at mist.io, creator of angularjs-recipes.com

Upload: marios-fakiolas

Post on 22-Mar-2017

1.393 views

Category:

Engineering


0 download

TRANSCRIPT

Page 1: Get rid of controllers in angular 1.5.x start using component directives

Get rid of controllers in AngularJS 1.5.x

Start using component directives

Fakiolas Marios - [email protected] / @fakiolinhoFrontend Developer at mist.io, creator of angularjs-recipes.com

Page 2: Get rid of controllers in angular 1.5.x start using component directives

What are component directives in AngularJS 1.5 ?

As of AngularJS 1.5.x release a new type of directives was introduced. These are component directives.

A component directive is a component with directives flavor.

This is a huge step which brings us closer to components logic even in AngularJS 1.5.x

We can now build an AngularJS 1.5.x application by replacing controllers with components.

So we can prepare even better our old applications for their upgrade to Angular 2 and its components ways.

Page 3: Get rid of controllers in angular 1.5.x start using component directives

Let’s create a simple component directive

// Create it

angular

.module('myApp')

.component('userGreeting', {

bindings: {

user: '='

},

controller: function() {

var self = this;

self.welcome = 'Welcome ' + self.user.name + '!';

},

template: '<h1>{{$ctrl.welcome}}</h1>'

});

// Use it

<user-greeting user="{name: 'John Doe'}"></user-greeting>

<user-greeting user="{name: 'Jane Doe'}"></user-greeting>

Page 4: Get rid of controllers in angular 1.5.x start using component directives

Analyze a simple component directive

name

This is the name of the component and the only required option. We should pick wisely a camel-case name to register our component and then call it into action using this. Be careful because it always maps to a dash-case component:

angular

.module('myApp')

.component('userGreeting', {

...

});

<user-greeting user="{name: 'John Doe'}"></user-greeting>

Page 5: Get rid of controllers in angular 1.5.x start using component directives

Analyze a simple component directive

bindings

This an optional parameter and it is the way to define DOM attribute binding to component properties. Component properties are always bound to the component controller.

angular

.module('myApp')

.component('userGreeting', {

bindings: {

user: '='

},

...

});

<user-greeting user="{name: 'John Doe'}"></user-greeting>

Page 6: Get rid of controllers in angular 1.5.x start using component directives

Analyze a simple component directive

controller

This is an optional parameter and by default an empty function is registered. Here we can use all attributes passed with bindings and run some logic.

angular

.module('myApp')

.component('userGreeting', {

bindings: {

user: '='

},

controller: function() {

var self = this;

self.welcome = 'Welcome ' + self.user.name + '!';

}

...

});

Page 7: Get rid of controllers in angular 1.5.x start using component directives

Analyze a simple component directive

template

This is an optional parameter which returns an empty string by default. We can register with it a html template as the content of our component. Check out offered $ctrl as a controller’s alias.

angular

.module('myApp')

.component('userGreeting', {

bindings: {

user: '='

},

controller: function() {

var self = this;

self.welcome = 'Welcome ' + self.user.name + '!';

},

template: '<h1>{{$ctrl.welcome}}</h1>'

});

Page 8: Get rid of controllers in angular 1.5.x start using component directives

Analyze a simple component directive

templateUrl

We could use this to call into action an external html file as our component’s template.

angular

.module('myApp')

.component('userGreeting', {

bindings: {

user: '='

},

controller: function() {

var self = this;

self.welcome = 'Welcome ' + self.user.name + '!';

},

templateUrl: 'greeting.html'

});

Page 9: Get rid of controllers in angular 1.5.x start using component directives

Are you still ok?

Page 10: Get rid of controllers in angular 1.5.x start using component directives

Let’s create a simple Blog application with component directives

https://github.com/Athens-AngularJS-Meetup/blog

Page 11: Get rid of controllers in angular 1.5.x start using component directives

Routing with component directives

// Routing using components instead of controllers

angular

.module('myApp')

.config(['$routeProvider', function($routeProvider) {

$routeProvider

.when('/', {

resolve: {

posts: function(Post) {

return Post.all();

}

},

template: '<posts posts="$resolve.posts"></posts>'

})

...

Page 12: Get rid of controllers in angular 1.5.x start using component directives

Declaring posts component

// Posts list component

angular

.module('myApp')

.component('posts', {

templateUrl: 'app/templates/posts.html',

bindings: {

posts: '='

},

controller: function() {

var self = this;

self.posts = self.posts.slice(0, 5);

}

});

Page 13: Get rid of controllers in angular 1.5.x start using component directives

Declaring posts list and post-item templates

// Posts list template

<section id="posts">

<post-item post="post" ng-repeat="post in $ctrl.posts"></post-item>

</section>

// Post list item template

<div class="post-item card">

<img ng-src="{{$ctrl.img}}" alt="{{$ctrl.post.title}}" />

<div class="card-body">

<h4>{{$ctrl.post.title}}</h4>

<hr>

<p>{{$ctrl.post.body}}</p>

<a ng-href="#/posts/{{$ctrl.post.id}}" class="btn">Read

More</a>

</div>

</div>

Page 14: Get rid of controllers in angular 1.5.x start using component directives

Declaring post-item component

// Post item component

angular

.module('myApp')

.component('postItem', {

templateUrl: 'app/templates/post-item.html',

bindings: {

post: '<'

},

controller: function() {

var self = this;

self.img = 'http://lorempixel.com/600/300/city/';

}

});

Page 15: Get rid of controllers in angular 1.5.x start using component directives

Declaring Post factory

// Posts factory

angular

.module('myApp')

.factory('Post', ['$http', function($http) {

var service = {

all: all,

get: get

};

return service;

function all() {

return $http

.get('http://jsonplaceholder.typicode.com/posts')

.then(function(data) {

return data.data;

});

}

...

Page 16: Get rid of controllers in angular 1.5.x start using component directives

Create even more componentslike social-icons

// Declare the component

angular

.module('myApp')

.component('socialIcons', {

templateUrl: 'app/templates/social-icons.html'

});

// Declare its template

<ul class="social-icons">

<li>

<a href="#"><i class="fa fa-twitter"></i></a>

</li>

...

</ul>

// Use the component

<social-icons></social-icons>

Page 17: Get rid of controllers in angular 1.5.x start using component directives

Components data bindings overview

Page 18: Get rid of controllers in angular 1.5.x start using component directives

Components bindings type does matter a lot

bindings: {

// Two way data-bindings (avoid usage)

posts: '=',

// One way data-bindings

// Preferable for Objects (highly proposed)

post: '<',

// Preferable for simple Strings

name: '@',

// Outputs data-bindings

onEdit: '&'

}

Page 19: Get rid of controllers in angular 1.5.x start using component directives

Components bindings type does matter a lot

Ideally, the whole application should be a tree of components that implement clearly defined inputs and outputs, and minimize two-way data binding. That way, it's easier to predict when data changes and what the state of a component is.

Inputs should be using < and @ bindings. The < symbol denotes one-way bindings (available since 1.5). The difference to = is that the bound properties in the component scope are not watched, which means if you assign a new value to the property in the component scope, it will not update the parent scope.

Page 20: Get rid of controllers in angular 1.5.x start using component directives

Components bindings type does matter a lot

Note however, that both parent and component scope reference the same object, so if you are changing object properties or array elements in the component, the parent will still reflect that change. The general rule should therefore be to never change an object or array property in the component scope.

Page 21: Get rid of controllers in angular 1.5.x start using component directives

Components cooperation

Of course components have outputs too. These are also declared in bindings and we use them to inform a parent component regarding an edit / delete / update action we want to execute.

Data flow always from parents to children and children never edit their inputs but emit the right callback events backwards to their parents requesting an action.

Outputs are realized with & bindings, which function as callbacks to component events.That way, the parent component can decide what to do with the event (e.g. delete an item or update the properties)

Page 22: Get rid of controllers in angular 1.5.x start using component directives

Components cooperation example

// Child's input / output bindings

bindings: {

task: '<',

onDelete: '&'

}

// Child's template

<p>{{$ctrl.post.title}}</p>

<button ng-click="$ctrl.onDelete({post: $ctrl.post})">Delete</button>

//Parent's template

<section id="posts">

<post-item post="post" on-delete="$ctrl.deletePost(post)" ng-repeat="post

in $ctrl.posts"></post-item>

</section>

// Parent's controller

ctrl.deletePost(post) {

...

}

Page 23: Get rid of controllers in angular 1.5.x start using component directives