I tried to wrap my head around concept of AngularJS component and I kinda started to understand the principle, but when I tried to practice it, I found an example when I'm not sure how to implement it with a component.
I need to implement linear progressbar, it has a template, so logically must be a component, not a directive, but I can't find a way to do DOM manipulations in component and it seems weird to have a directive inside such a little component. Here is the basic implementation with directive:
JS
angular.module('test', [])
.controller('MainCtrl', function($q, $scope) {
$scope.curVal= 0;
$scope.maxVal = 100;
})
.directive('progressBar', [function () {
return {
restrict: 'E',
scope: {
curVal: '@',
maxVal: '@'
},
template: "<div class='progress-bar'>"+
"<div class='progress-bar-bar'>testing</div>"+
"</div>",
link: function ($scope, element, attrs) {
function updateProgress() {
var progress = 0;
if ($scope.maxVal) {
progress = Math.min($scope.curVal, $scope.maxVal) / $scope.maxVal * element.find('.progress-bar').width();
}
element.find('.progress-bar-bar').css('width', progress);
}
$scope.$watch('curVal', updateProgress);
$scope.$watch('maxVal', updateProgress);
}
};
}]);
HTML
<progress-bar cur-val='{{curVal}}' max-val='{{maxVal}}'>
CSS
.progress-bar {
width: 120px;
height: 18px;
border-style: solid;
border-width: 1px;
background-color: rgba(100,50,100,.60);
border-color: #aaa;
}
.progress-bar-bar {
width: 0px;
background-color: rgb(100,50,100);
height: 100%;
color: #fff;
font-weight: normal
}
So, maybe I understood the principle of a component wrong, but I really googled a lot about it and thought that I understood the principle before I faced this example.
So my question is: Can I manipulate DOM in component in any way and if the answer is no, what is the way to implement this directive in component (and is it suitable at all)? I don't feel that adding directive to component just to change some CSS is an appropriate choice, so I'm stuck.
To address your confusion about component vs directive, to use one over the other is a matter of how you design your application.
If you prefer to stick to an MVC (MVVM, MVW, MV*) architecture, it makes little sense to have components. You just create views, controlled by controllers and directives that will modify or control some DOM elements.
In an MV* app there are some cases where you really want to separate a block from the rest of the page and even make it reusable. You still can make a component for it but it makes more sense in that architecture to stick with a directive.
Since 1.5, directive come very close to what components are. You can get rid of the scope, create a controller...etc, you just have a little more boilerplate code to write.
If you want your app to follow a component architecture (react, web components, angular2...etc.) then everything in the application should be a component. (login, navigation, footer...etc) and components can have smaller components. (a file upload component could contain a progress bar component)
When more control over DOM elements is needed, this is when you use directives. If no existing angular directive work for you (ngStyle, ngClass, ngShow...etc.) you create yours. (You want an input to get focus automatically, you can create a directive)
To answer the progress bar thing, this is how I would write its component:
var progressBar = {
bindings: {
width: '<'
},
template: `<div class="meter">
<span ng-style="{ 'width' : $ctrl.width }"></span>
</div>`
}
https://plnkr.co/edit/rz8AVALGVl5EiZR1OUdK?p=preview
PS: The css style was copied from css-tricks to save time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With