Reputation: 830
I have written a custom directive to format a value, which is given below
var directiveapps = angular.module('myApp.currencyValues', []);
directiveapps.directive('currencyValue', function () {
return{
scope: {
data: '=items'
},
template: '<div>$ {{value|number}}</div>',
link: function(scope){
scope.value = Math.round(scope.data* 100) / 100;
}
};
});
This directive will format a value to a currency and also it will round off the decimal points.This directive works fine, but my issue starts when calling the directives. i calls the directive from the view like this
<div class="overallsummary_meter_txt left">
Total Price<br>
<span currency-value items="totalPrice" class="orange_txt"></span>
</div>
the price amount coming from the db is assigned to 'items' and it will be passed in to the directive,this works in some case and getting formatted price value. now my issues are
In some cases i am getting empty value (only $ sign without formatted value) while calling the directive.But in this same case if i hard code some values to items(items=8888), then it works. what is wrong with this directive?
I think this directive is not two way binded, if not how can i make that?
A label added after calling a directive is not displaying. I will give an example
<div currency-value items="downPayment">/Month</div>
here the "/Month" is not displaying,but the formatted value is showing. How to add something in the same div after calling a directive?
view:- Price Range : $ 1000 - $ 500
<span class="price_range">{{maxMarcketPrcie}} - {{minMarcketPrice}}</span>
in this case how can i pass two values in to 'items' at a time? is there any alternate way to achieve this?
Upvotes: 2
Views: 78
Reputation: 4360
1- I see nothing wrong with your directive. In the snippet below I haven't changed much from your example. (only replaced scope variable by controllerAs syntax) The only thing is, if you just want to round a number you can use a filter instead of a directive.
2- items uses two way binding. Nothing strange there. Maybe there's something in your controller that causes bugs?
function currencyValue() {
return{
scope: {
data: '=items'
},
template: '<div>$ {{value|number}}</div>',
link: function(scope){
scope.value = Math.round(scope.data* 100) / 100;
}
};
};
function MyController() {
this.items = 123.666;
}
angular.module('myApp', []);
angular
.module('myApp')
.controller('MyController', MyController)
.directive('currencyValue', currencyValue);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyController as ctrl" class="overallsummary_meter_txt left">
Total Price<br>
<span currency-value items="ctrl.items" class="orange_txt"></span>
</div>
</div>
3- The "label" you want to add is made by transclusion. You need to add transclude: true
and ng-transclude
in your directive. It will copy all the elements from your directive to your template:
function currencyValue() {
return{
transclude: true,
scope: {
data: '=items'
},
template: '<div>$ {{value|number}}<span ng-transclude></span></div>',
link: function(scope){
scope.value = Math.round(scope.data* 100) / 100;
}
};
};
function MyController() {
this.items = 123.666;
}
angular.module('myApp', []);
angular
.module('myApp')
.controller('MyController', MyController)
.directive('currencyValue', currencyValue);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyController as ctrl" class="overallsummary_meter_txt left">
Total Price<br>
<span currency-value items="ctrl.items" class="orange_txt">/Month</span>
</div>
</div>
4- To pass a range to your directive you have 2 possibilities:
itemsMin="itemsMin"
and
itemsMax="itemsMax"
Or better you change your items variable to an object:
this.items = {rangeFrom:1000, rangeTo:5000};
Your directive then becomes something like:
return{
transclude: true,
scope: {
data: '=items'
},
template: '<div>$ {{value.rangeFrom|number}} - $ {{value.rangeTo|number}}<span ng-transclude></span></div>',
link: function(scope){
scope.value = {};
scope.value.RangeFrom = Math.round(scope.data.rangeFrom* 100) / 100;
scope.value.RangeTom = Math.round(scope.data.rangeTo* 100) / 100;
}
};
Upvotes: 2
Reputation: 1304
1) Since you are telling the price is empty in some cases and works fine when you hardcode, then the problem is with db response. Check the response is giving the totalPrice
.
Still its better to write your directive below format:
directiveapps.directive('currencyValue', function () {
return{
scope: {
items: '='
},
template: '<div>$ {{value|number}}</div>',
link: function(scope){
scope.value = Math.round(scope.items* 100) / 100;
}
};
});
and call it as
<div class="overallsummary_meter_txt left">
Total Price<br>
<span currency-value items="totalPrice" class="orange_txt"></span>
</div>
Same way what you did.
Note: In directive
scope: {
items: '='
}
items: '=' means its two way binding from a scope, you can also use '<' for one way binding from a scope, or '@' for one way binding from a string.
2) /Month this won't work because the directive will replace the content inside the div with its template. The quickest way for solving your issue is to move the content into directive's template. Like:
change
template: '<div>$ {{value|number}}</div>',
to
template: '<div>$ {{value|number}} /month</div>',
JFYI: We can also use ngTransclude for adding dynamic content.
Upvotes: 0