I have an element directive and I want to know if I can get parameters from routeProvider to render my template and set it up in my controller.
adminDash.directive('hospitals', function() {
return {
restrict: 'E',
templateUrl: 'www/partials/admin/hospitals.html',
controller: 'AdminHospitalsController',
controllerAs: 'hospitalsCtrl',
};
});
How can I get any parameters in my element directive?
You can isolate the scope of the directive, like this:
adminDash.directive('hospitals', function() {
return {
restrict: 'E',
templateUrl: 'www/partials/admin/hospitals.html',
controller: 'AdminHospitalsController',
controllerAs: 'hospitalsCtrl',
scope: {
paramValue: '&',
paramVariable: '=',
},
};
});
check this to understand better https://thinkster.io/egghead/isolate-scope-am/
There are 2 ways to do it: both involve using $routeParams service that allows you to retrieve current set of route parameters.
Given that you have an url: http://example.com/#/hospitals/foobar and a route /hospitals/:hospital/ configured in your $routeProvider, you can:
1.Inject $routeParams into your directive:
adminDash.directive('hospitals', function($routeParams) {
return {
restrict: 'E',
templateUrl: 'www/partials/admin/hospitals.html',
controller: 'AdminHospitalsController',
controllerAs: 'hospitalsCtrl',
link: function(scope, element){
scope.hospital = $routeParams.hospital;
}
};
});
2.Inject $routeParams into AdminHospitalsController
adminDash.controller('AdminHospitalsController', function($scope, $routeParams) {
$scope.hospital = $routeParams.hospital;
}
Both method will result in having hospital=foobar in your directive's scope;
Related
I am trying to retrieve html code from a URL to use as my templateUrl and using getTrustedHtml to do it, however, I'm receiving a $sce:unsafe error.
app.directive('showResult', ['$sce', function($sce){
return {
restrict: 'E',
scope: {
info: '='
},
templateUrl: $sce.getTrustedHtml('https://raw.githubusercontent.com/aidanhall21/aidanhall21.github.io/master/showResult.html')
};
}]);
Here is a working solution for you: http://jsfiddle.net/yvbenitah/U3pVM/57716/
2 things:
you need to use trustAsResourceUrl, because you want to access a remote URL: angularjs doc.
directive will be like this:
.directive('showResult', ['$sce', function($sce){
return {
restrict: 'E',
scope: {
info: '='
},
templateUrl: $sce.trustAsResourceUrl('https://raw.githubusercontent.com/aidanhall21/aidanhall21.github.io/master/showResult.html')
};
You have to do the binding correctly if you want the string to be displayed.Where the directive will be used, you have to do
.controller('testCtrl', function($scope){
$scope.coucou = {name:"A NAME HERE"};
})
and in your html:
<show-result info="coucou"></show-result>
enjoy!
I'm using angular 1.5 to build a directive that I can use in different situations. I want to be able to pass in data from the controller to the directive as an object. My set up is something like this:
Controller:
function ControllerWrapper($scope, $location, $window){
$scope.depth= 99;
$scope.filter = {filters: [{column: 'stage', values: ['Closed']}]};
}
HTML:
<div ng-controller="ControllerWrapper">
<my-great-directive max-depth="{{depth}}" filters="filter"></my-great-directive>
</div>
Directive return
return {
restrict: 'E',
templateUrl: function(element, attributes) {
return attributes.templateUrl;
},
link: function(scope, element, attributes) {
var obj = scope.$eval(attributes.filters);
var dir = scope.$eval(attributes.dir);
scope.$watch("filters",function(newValue,oldValue) {
if(scope.vm.dir != null){
scope.vm.dir.rows = scope.filterTreeGrid();
}
}, true);
},
controller: DirectiveController,
controllerAs: 'vm',
bindToController: true,
scope: {
maxDepth: '#',
filters: '=?'
}
};
From what I've read the filters: '=' should be enough to pass the data through but I'm getting a null after it tries to resolve it. Any suggestions?
Using Angular 1.6 I am defining an directive like so:
angular
.module('myApp')
.directive('lyEntity', lyEntity);
function lyEntity() {
return {
restrict: 'E',
scope: {
model: '=',
type: '#'
},
controller: 'lyEntityController',
controllerAs: 'vm',
bindToController: true,
templateUrl: function (elem, attrs) {
return 'components/_templates/' + attrs.type + '.html'
}
};
}
But using it in another template like so:
<ly-entity model="vm.entity" type="{{vm.type}}"></ly-entity>
will result in templateURL components/_templates/{{vm.type}}.html
How can I hand over the value of vm.type to be used in my templateUrl function?
Yeah, it can't be done the way you're trying to do it because templateUrl function is called before the attributes are interpolated. One way to achieve this would be using ng-include.
return {
restrict: 'E',
scope: {
type: '#'
},
link: function(scope, element, attrs){
$scope.templateUrl = 'components/_templates/' + attrs.type + '.html';
},
template: '<ng-include src="templateUrl"/>'
};
So, construct the template url in controller, have ng-include as the template and point the src to the constructed template url.
Here's a good article on how to have dynamic templates: https://medium.com/angularjs-meetup-south-london/angular-directives-using-a-dynamic-template-c3fb16d03c6d#.mizywdk6s
Thanks to #Chantu, I found a solution which is working for me:
Directive:
angular
.module('myApp')
.directive('lyEntity', lyEntity);
function lyEntity() {
return {
restrict: 'E',
scope: {
model: '=',
type: '='
},
controller: 'lyEntityController',
controllerAs: 'vm',
bindToController: true,
template: '<ng-include src="templateUrl"/>'
};
}
Controller:
$scope.templateUrl = 'components/_templates/' + vm.type + '.html';
and call it:
<ly-entity model="vm.entity" type="vm.type"></ly-entity>
I have the following code. Why doesn't the vm.name work? Why is the this inside the controller not being detected? Haven't I defined a closed scope for the directive?
What am I doing wrong?
var mod = angular.module('myApp', []);
mod.directive('myObj', myObject);
function myObject(){
return {
restrict: 'E',
templateUrl: 'my-obj.html',
scope: {},
controller: myController
};
function myController(){
var vm = this;
vm.name="vfdfbdn";
}
}
To use this in controller inside directive you need to use controllerAs: 'ctrl' but then in template you will need to prefix all name with {{ctrl.name}} or you can use $scope like:
function myController($scope) {
$scope.name="vfdfbdn";
}
function myObject(){
return {
restrict: 'E',
template: '<div>{{c.name}}</div>',
scope: {},
controller: myController,
controllerAs: 'c'
};
function myController(){
var vm = this;
vm.name="vfdfbdn";
}
};
Please see this question to understand the things
You need to tell Angular how you are going to reference the this from the controller in the view.
function myObject(){
return {
restrict: 'E',
templateUrl: 'my-obj.html',
scope: {},
controller: myController,
controllerAs: 'ctrl'
};
}
Now you can reference everything that you assigned to this, that you named vm in your controller with ctrl.
I used ctrl to show that there is no correlation between the name you use to refere to it in the view, setted with controllerAs and the name you give to this inside the controller function. It is a normal to reference different controllers with different controllerAs references so you can now which controller they refer to in the view.
Try this:
function myObject() {
return {
restrict: 'E',
templateUrl: 'my-obj.html',
scope: {},
bindToController: true,
controller: myController
};
}
myController.$inject = ['$scope'];
function myController($scope){
var vm = this;
vm.name="vfdfbdn";}
Say you have an AngularJS directive in which you want to set the controller attribute and the controllerAs attribute to the same string.
Ex.
angular.module('blahModule', [])
.directive('blahDirective', function(){
return {
restrict: 'E',
controller: 'blahController',
controllerAs: 'blahController',
templateUrl: 'blah/blah.html'
}
});
The above is valid and works, but it feels redundant to when setting the controller and controllerAs value to the same thing. Is there way to do it in one attribute? Like:
angular.module('blahModule', [])
.directive('blahDirective', function(){
return {
restrict: 'E',
controllerAndControllerAs: 'blahController',
templateUrl: 'blah/blah.html'
}
});
Thanks in advance!
You can use
controller: 'blahController as blahController',