I am trying to write a custom directive that will "create" a dashboard widget including:
Here is how far I got with my directive:
app.directive('widget', function () {
return {
restrict: 'E',
scope: {
title: '@',
schema: '&',
data: '&'
},
template: '<div>' +
'<span class="widget-title">{{title}}</span>' +
'<div schema="schema()" data="data()"></div>' +
'</div>'
}})
and my html:
<widget title="Number of users" options="numberWidget" data="userData">
</widget>
I am stuck on how to "bind" the data to the schema, and where I should define the different schemas (or widget models). Maybe my approach is wrong, so a little direction would be much appreciated. I can provide more info if needed.
EDIT: Here is a CodePen i made of how far I am and what I thought I could achieve - maybe it can be (or should be) done differently.
Ok, so I decided to do it slightly differently to what I though it worked. Here is my solution:
Directive:
The directive is restricted to an Element and has an isolated scope which takes some arguments, the data with '&'
, which evaluates an expression (the expression is defined in the controller as a function shown below) and the classes and title with '@'
, which evaluate a string (these strings are defined in the HTML shown below)
app.directive('widget', ['$log', function ($log) {
return {
restrict: 'E',
scope: {
data: '&',
valueClass: '@',
keyClass: '@',
widgetTitle: '@',
titleClass: '@'
},
template:
'<div><span class="{{titleClass}}">{{widgetTitle}}</span></div>' +
'<div><span class="{{valueClass}}">{{data().value}}</span></div>' +
'<div><span class="{{keyClass}}"> {{data().key}}</span></div>',
link: function (scope, element, attrs) {
scope.$watch('data', function (newValue, oldValue) {
if (newValue !== oldValue) {
scope.data = newValue;
$log.info('updating data');
}
}, true);
}
};
}]);
HTML: The HTML then initializes the 'widget' element created from the directive like so:
<widget title-class="widget-title"
widget-title="Number of Users"
data="userData"
value-class="number-widget"
key-class="description">
</widget>
The data attribute calls a $scope
variable from the controller
Controller:
The controller simply fetches the data required in this example, it is a dummy object defined on $scope
called $scope.userData
:
app.controller('dashboardCtrl', [
'$scope', function ($scope) {
$scope.userData = {
key: 'Total Users',
value: 100
};
}
]);
CSS: The CSS obviously defines the classes used in the HTML element, this is down to preference of styling but just for my example I will show them:
.widget-title {
//whatever you need
}
.number-widget {
//whatever you need
}
.description {
// whatever you need
}
I hope this helps someone, any maybe there's a better way of doing but this suited my needs.