With the release of Angular 1.5 we can use the .component() shortcut to create component directives.
Do you have any suggestions in the way to use it ?
I have been a big follower of your styleguide for some time and here is how I usually write them.
Small ones, without the need of a controller, I like to write the template inside the same file as the return value of a hoisted function
(function() {
'use strict';
var componentConfig = {
template: generateTemplate(),
bindings: {
kpiVal: '=',
kpiLabel: '=',
},
};
angular
.module('app.utils.kpi')
.component('sfKpi', componentConfig);
//
function generateTemplate() {
return [
'<div class="sf_kpi">',
' <div class="sf_kpi__number">{{ $ctrl.kpiVal }}</div>',
' <div class="sf_kpi__label">{{ $ctrl.kpiLabel }}</div>',
'</div>',
].join('');
}
}());
For more advanced ones I like to put the template in a separate file and use 'templateUrl' property.
(function() {
'use strict';
var componentConfig = {
templateUrl: 'components/active-places/active-places.widget.html',
controller: controller,
};
angular
.module('app.widget.activeplaces')
.component('activePlaces', componentConfig);
/* @ngInject */
function controller($log, activityService) {
var vm = this;
vm.activities = [];
vm.isLoading = true;
vm.doFunnyStuff = doFunnyStuff;
activate();
function activate() {
$log.info('馃憡 activating activePlaces component');
activityService.getActivites()
.then(fetchData)
.catch(handleError)
.finally(stopLoader);
//
function fetchData(activities) {
vm.activities = activities;
$log.log('馃憮 activePlaces activities fetched: ', activities);
}
function handleError(err){
$log.error('馃挜 problem fetching activePlaces data', err);
}
function stopLoader() {
vm.isLoading = false;
$log.info('馃挭 activePlaces component started');
}
}
// methods
function doFunnyStuff() {
vm.activities.push('yolo');
}
}
}());
I am also curious about your opinion about the $onInit hook and how do you think components should be tested.
Thanks
(function() {
'use strict';
var componentConfig = {
bindings: {
data: '<'
},
templateUrl: 'components/active-places/active-places.widget.html',
controller: 'ActivePlacesController as vm',
};
angular
.module('app.widget.activeplaces')
.component('activePlaces', componentConfig)
.controller('ActivePlacesController', ActivePlacesController);
/* @ngInject */
function ActivePlacesController($log, activityService) {
var vm = this;
vm.activities = [];
vm.isLoading = true;
vm.doFunnyStuff = doFunnyStuff;
// methods
function doFunnyStuff() {
vm.activities.push('yolo');
}
}
}());
This way the controller can be tested.
Personally I prefer this way.
(function() {
'use strict';
angular
.module('app.widget.activeplaces')
.component('activePlaces', {
bindings: {
data: '<'
},
templateUrl: 'components/active-places/active-places.widget.html',
controller: 'ActivePlacesController as vm',
})
.controller('ActivePlacesController', ActivePlacesController);
function ActivePlacesController($log, activityService) {
var vm = this;
vm.activities = [];
vm.isLoading = true;
vm.doFunnyStuff = doFunnyStuff;
// methods
function doFunnyStuff() {
vm.activities.push('yolo');
}
}
}());
This way the controller can be tested.
@softsimon: v1.5.0
introduces ngMock#$componentController, so you don't have to register the controller separately for testability's sake :smiley:
I can second, thx @gkalpak . @softsimon you can simply skip this line from above:
.controller('ActivePlacesController', ActivePlacesController);
I also big fan of this style guide.
@xavhan for $onInit
I would use this way in your example:
vm.$onInit = activate;
function activate() {
}
I might call it init
and not activate from v1.5.0.
I also curious what @johnpapa think about this, appreciate.your guidance in advance.
:+1: for
vm.$onInit = activate;
function activate() {
}
closed for #766 to be the place for component discussion
Most helpful comment
I can second, thx @gkalpak . @softsimon you can simply skip this line from above:
.controller('ActivePlacesController', ActivePlacesController);
I also big fan of this style guide.
@xavhan for
$onInit
I would use this way in your example:vm.$onInit = activate;
function activate() {
}
I might call it
init
and not activate from v1.5.0.I also curious what @johnpapa think about this, appreciate.your guidance in advance.