AngularJS: Directive - Passing strings without having to use quotes - javascript

Here's a directive I created:
HTML:
<p-test something="'bla'"></p-test>
JavaScript:
.directive('pTest', function() {
return {
scope: {
something: '=?'
},
templateUrl: 'components/testTemplate.html',
controller: 'testController'
};
});
I'd like to be able to pass 'bla' as a string without the '', in the following way:
<p-test something="bla"></p-test>
I know it's possible via the attributes parameter in link, but it's irrelevant in this case (correct me if I'm wrong) as I'm passing these parameters directly to scope.

I'd like to be able to pass 'bla' as a string without the '', in the following way:
You would just need text binding (#) binding for that, instead of 2 way binding.
.directive('pTest', function() {
return {
scope: {
something: '#?' //<-- Here
},
templateUrl: 'components/testTemplate.html',
controller: 'testController'
};
});
and with the text binding if you want to bind scope properties then use interpolation. i.e example if bla is a scope variable holding a string then just do:
<p-test something="{{bla}}"></p-test>
Plnkr

Related

Using directive scope to update Highcharts

I have two charts with different ids (#chart1 and #chart2). I've created a button, so I can change a chart's type (e.g. from column to line):
<button ng-click="updateChart(name, 'line')">Line</button>
This button calls the updateChart function:
$scope.updateChart = function(id, type) {
var chart = $('#' + id).highcharts();
chart.series[0].update({
type: type
});
};
As I need to call the button for every chart, I've created a directive passing a name value to the scope:
.directive('changeChart', function() {
return {
restrict: 'E',
scope: {
name: '#'
},
templateUrl: "change-chart.html"
};
})
In my HTML I call the directive passing the chart id: <change-chart name="chart1"></change-chart>
However, the button isn't working. It only works if I remove the directive scope and set the id manually. Any ideas on how to solve this?
Here's a Plunker: http://plnkr.co/edit/5wmLldmXpoq9wiMACbNS?p=preview
That is because when you define a scope object in your directive, it creates an isolate scope for that directive. That means, the scope within your directive cannot access the scope properties defined outside. You have your controller defined on the outer scope where you attach the function updateChart. So, your isolate scope directive is not aware of this method.
To fix this, you can define a controller on your directive itself. And in that controller, define the method updateChart
.directive('changeChart', function() {
return {
restrict: 'E',
scope: {
name: '#'
},
controller: function ($scope) {
$scope.updateChart = function(id, type) {
var chart = $('#' + id).highcharts();
chart.series[0].update({
type: type
});
};
},
templateUrl: "change-chart.html"
};
})

template function not interpolating component bindings

I'm using 1.5 components, I don't think that matters though.
I'm trying to do a single = binding between a parent controller and a child directive isolate scope. The child isolate scope is interpolating the binding literally; instead of vm.data interpolating to the data I defined in the controller, it's coming out literally vm.data as a string.
If I try one way binding with # then, again, the "interpolated" value results in {{vm.data}} literally.
How can I get the string defined in the parent controller into the child component's template?
angular
.module('app', [])
.controller('Ctrl', function () {
this.str = '<0>, blah, <1>';
})
.component('appComponent', {
restrict: 'E',
controller: 'Ctrl as vm',
template: '<div><app-str appstr-data="{{vm.str}}"></app-str></div>'
})
.component('appStr', {
bindings: { appstrData: '#' },
restrict: 'EA',
template: function($element, $attrs) {
console.log($attrs.appstrData)
return '<span>'+$attrs.appstrData+'</span>';
}
});
https://plnkr.co/edit/VWVlhDbhP2uDRKtXJZdE?p=preview
If you wanted to get the string defined in parent controller to get render in child you should use {{appStr.appstrData}} interpolation only to use it inside child template.
Very first thing you need to change is, you are returning incorrect template from appStr template.
Instead of
return '<span>'+$attrs.appstrData+'</span>';
Use
return '<span>{{appStr.appstrData}}</span>';
Basically you should use component name to have access to component bindings, like here component name is appStr so that's why binding of variable could be accessible using {{appStr.appstrData}}
Component
.component('appStr', {
bindings: { appstrData: '#' },
restrict: 'EA',
template: function($element, $attrs) {
return '<span>{{appStr.appstrData}}</span>'; //<--change here
}
});
Demo Plunkr
Plunkr with = binding
Plunkr with no bindings (isolate: false) means no isolated scope

Angular controllerAs and parameter

I m actually creating a little directive and I m facing a problem with the scope object and controllAs.
In fact, I have this result :
angular.module('app')
.directive('historyConnection', function () {
return {
templateUrl: 'views/directives/historyconnection.html',
restrict: 'E',
scope: {
idUser: '#iduser'
},
controller:function($scope){
console.log(this.idUser); // gives undefined
console.log($scope.idUser); // gives the good value
},
controllerAs:'history'
};
});
From the html code :
<history-connection iduser="55"></history-connection>
I dont know how to make controllerAs work when passing parameters to directive. Can you help me ?
Important informations are commented in the javascript code above
If you want the scope properties to be bound to the controller you have to add bindToController: true to the directive definition.

ng-click loose the function context

I am using angularjs.
I have a directive that gets a function as parameter:
module.directive('someDirective', [function () {
return {
restrict: 'E',
template: <button ng-click="doClick()">blabla</button>,
scope: {
doClick: '='
}
};
}]);
I am using this directive like that:
<some-directive do-click="funcOnScope"></some-directive>
And everything works perfectly.
Now I have the following on my scope:
$scope.a = {
data: { name: 'myname' },
action: function() {
alert(this.data.name);
}
}
When calling to:
<some-directive do-click="a.action"></some-directive>
I am expecting to get an alert with 'myname' when clicking on the button. But I get an exception that data is undefined. This is happening because "this" is referencing to window (angular calls to the ng-click function without a context).
How can I call a.action() without loosing the context?
change the scope definition to
scope: {
doClick: '&'
}
and call it like that
<some-directive do-click="a.action()"></some-directive>
here is jsfiddle
I don't know if this is the correct answer, but it will suffice. Perform a bind on a.action in the do-click attribute:
<some-directive do-click="a.action.bind(a)"></some-directive>
This will force the function to keep the a context.

Pass additional parameter to template using AngularJS

I have the following directive:
app.directive("actTemplate", function() {
return {
restrict: 'A',
templateUrl: "/views/myTemplate.html"
};
});
how can i pass additional parameter to myTemplate so:
<div>
{{aditionalParam}}
...
</div>
takes the value?
Define
app.directive("actTemplate", function() {
return {
restrict: 'A',
templateUrl: "/views/myTemplate.html"
scope: {
foo: '=boo'
}
};
});
Template
<div>
{{foo}}
</div>
Use
<actTemplate boo="lalala" />
You have to specify that your directive should create it's inner scope. Scope variable could then be shared in single or double binding way (see directive scope binding doc)
app.directive("actTemplate", function() {
return {
restrict: 'A',
scope: {
additionalParam: '='
},
template: "<div>{{additionalParam}}</div>"
};
});
Then "call" your directive with this dashed syntaxe:
<div act-template additional-param="foobar">
You can have one-way binding (controller -> directive) like in this jsfiddle example.
Or two way data binding (controller <-> directive) , like in this one.

Categories

Resources