Passing template URL to directive from controller - angularjs

I am trying to send template url from controller to the directive. Hardcoding the template url works fine. Here is what works:
<div my-directive template-url = "my-template.html" ></div>
And in directive
return {
restrict: 'AEC',
templateUrl: function (tElement, tAttrs) {
return tAttrs.templateUrl;
},
controller: 'myController as myCtrl',
scope: {
myDirective: '='
}
};
But I want to use my controller variable when specifying the template-url in the directive. So I tried:
<div nav-switcher template-url="baseCtrl.directiveUrl" ></div>
For which Im getting error message:
Error: [$compile:tpload] Failed to load template: "baseCtrl.directiveUrl"
How to pass controller variable to the directive ?

I think perhaps if you change you HTML to
<div nav-switcher template-url="{{directiveUrl}}" ></div>
The braces will evaluate the expression to text.

Related

Nesting directives, both with template url

I have 2 directives within a module. Within one of them, is a templateUrl property. Within that templateUrl, I've made a reference to the other directive, which in turn has a templateUrl.
e.g.
<div> <!--This is my first partial page which uses the SelectorResult directive -->
Here are some results
<div result-carousel>
<!-- here is where some more html should go from result-carousel -->
</div>
</div>
From the module with the directives:
app.directive('SelectorResult', function () {
return {
restrict: 'AE',
scope: {},
templateUrl: '/chooser/Pages/partials/selector-result-tmpl.aspx',
replace: true,
controller: 'SelectorResultController',
controllerAs: 'resultCtrl'
};
});
app.directive('resultCarousel', function () {
return {
templateUrl: '/chooser/Pages/partials/carousel-tmpl.html'
};
});
This is the error I'm getting:
[ngTransclude:orphan] http://errors.angularjs.org/1.2.28/ngTransclude/orphan?p0=%3Cdivlass%3D%carousel-inner%22%20ng-transclude%3D%22%22%3E
I get an error about transclusion, and I've tried some things, but no change. I thought you folks might have ideas.

angularjs custom directive conditional templateUrl via attribute

I am trying to load conditional template urls via attributes, my directives is as follows.
The directive is in a ng-repeate and when box.key == 'experiences' the expression is returning education-form.php and not experiences-form.php.
<div multiple-form
directive-data='directiveData'
template-url="box.key == 'experiences'? 'experiences-form.php':'education-form.php'"
item="item"
forms="forms"
form-name="{{box.key}}{{item._id}}"
onsave="updateMultipleUser(box.key, item._id, $data)"
onreset="formAction($formName, 'reset')"
cancel="formAction($formName, 'cancel')"
>
</div>
Directive DDO
{
restrict: 'A',
replace: true,
scope: {
directiveData: '=',
onsave: '&',
onreset: '&',
cancel: '&',
formName: '#',
forms: '=',
item: '='
},
controller: controller,
templateUrl: function(tElement, tAttrs) {
return $rootScope.$eval(tAttrs.templateUrl);
}
}
attempting using link function
<div multiple-form
directive-data='directiveData'
template-map="{
experiences:'experiences-form.php',
courses:'education-form.php'
}"
box="box"
item="item"
forms="forms"
form-name="{{box.key}}{{item._id}}"
onsave="updateMultipleUser(box.key, item._id, $data)"
onreset="formAction($formName, 'reset')"
cancel="formAction($formName, 'cancel')"
>
</div>
controller: controller,
link: function(scope, element, attrs) {
// shows correct template url ... now what?
console.log(scope.templateMap[scope.box.key]);
},
templateUrl: function(tElement, tAttrs) {
return 'experiences-form.php';
}
Markup
<div multiple-form
directive-data='directiveData'
ng-attr-template-url="{{box.key == 'experiences'? 'experiences-form.php':'education-form.php'}}"
item="item"
forms="forms"
form-name="{{box.key}}{{item._id}}"
onsave="updateMultipleUser(box.key, item._id, $data)"
onreset="formAction($formName, 'reset')"
cancel="formAction($formName, 'cancel')"
>
</div>
Then your templateUrl function would be
templateUrl: function(tElement, tAttrs) {
$timeout(function(){ //wait until the ng-attr evaluates a value.
return tAttrs.templateUrl;
})
}
Not sure it will work or not.
Update
Another obivious way would be loading template from the link function and append it from there it self rather than having call template through templateUrl
HTML
<div multiple-form
directive-data='directiveData'
template-path="{{box.key == 'experiences'? 'experiences-form.php':'education-form.php'}}"
item="item"
forms="forms"
form-name="{{box.key}}{{item._id}}"
onsave="updateMultipleUser(box.key, item._id, $data)"
onreset="formAction($formName, 'reset')"
cancel="formAction($formName, 'cancel')">
</div>
Directive
{
restrict: 'A',
replace: true,
scope: {
directiveData: '=',
onsave: '&',
onreset: '&',
cancel: '&',
formName: '#',
forms: '=',
item: '=',
templatePath: '#'
},
controller: controller,
link: function(scope, element, attrs){
//here you will have template path in your scope.templatePath variable
//you can load template using it.
var template = getTemplate(); //this can be done by below mentioned way
element.append($compile(template)(scope));//addding compiled element
}
}
Inside your link function you could append directive template by loading template on demand, there are several way to load template from directive
Using $templateCache
While using $templateCache you need to put that template in angular $templateCache at the run phase,
app.run(function($templateCache){
$templateCache.put('myTemplate.html', '<div>myTemplate</div>')
})
After doing this you could eaisily access that template in directive just by adding $templateCache.get('myTemplate.html')
Another way of adding template in $templateCache would be using script tag with type="text/ng-template"
<script type="text/ng-template" id="myTemplate.html">
<div>myTemplate</div>
</script>
Using $http.get
You could do get the template by using $http.get('myTemplate.html') in success of it you will get data that is nothing but html content that file. You could compile and append that html to your directive element.
Using ng-include
You could use ng-include directive here. You need to do create a dummy div that will have an ng-include directive with desired template-path like <div ng-include="templatePath"></div>,it will load a template in that div. If you don't want to use div then you could use <ng-include src="templatePath"></ng-include>. But this is not much preferable way of doing code. because it does create child scope like ng-repeat does.

Databinding to a controller inside a directive in angular

I'm new to angular and have the following directive:
angular.module('myApp')
.directive('myDirective', function () {
return {
templateUrl: '/views/partial-views/partial.html',
restrict: 'E',
controller : function(){
age : '5'
},
controllerAs : 'myCtrl'
};
});
I want to include the age on my page inside partial.html which looks like this:
<div ng-app="myApp" ng-controller="myCtrl as s">
{{s.age}}
</div>
However I am getting the following error:
Error: [ng:areq] Argument 'myCtrl' is not a function, got Object
Can anybody tell me what I'm doing wrong?
What Chandermani mentioned is absolutely correct. To be more precised, it can be written as,
Directive Definition
angular.module('myApp')
.directive('myDirective', function () {
return {
templateUrl: '/views/partial-views/partial.html',
restrict: 'E',
controller: ['$scope', function($scope){
$scope.age = '5'
}]
};
})
Usage
<div ng-app="myApp">
<my-directive>
{{age}}
</my-directive>
</div>
However, there's no meaning of defining a directive here. You can just use a controller definition to fulfill the same action.
There were two issues with you code. Firstly you don't to alias the controller again, by using ng-controller in your template so that needs to be removed.
Secondly the controller is a function not object, so use:
this.age = '5';

How to use custom directives.

I have mentioned HTML code below
<div class="panel" ng-controller="myController">
<div myArr="arr" my-Dir="">
</div>
JavaScript is
app.controller('myController',['$scope',function($scope){
// here i have one array of objects arr is here
}])
and Directive is
app.directive("myDir", function() {
scope: {
myArr: "=",
},
templateUrl: "views/myHTML.html"
};
});
Here I am including myHTML.html file. How do I pass the array to this file?. I need this array in myHTML.html file. I want to display the array elements in the myHTML using the ng-repeat.
You are using dayArr in the html and then trying to isolate your scope on something called dayArray. These don't match up. You also need to pass the array into dayArr so that it can actually have a value in your scope
I've updated the fiddle to have a working example http://jsfiddle.net/zpWsz/2/
This is the relevant bits:
Here is where I pass in some dummy array.
<div my-dir="" day-arr="[1,2,3]" >
Here is the updated directive pieces:
scope: {
dayArr : "="
},
template: '<ul>' +
'<li ng-repeat="i in dayArr">{{ i }}</li>' +
'</ul>',
A templateUrl would work too, but how you had it in the fiddle was throwing js errors.
Hope this helped.
custom directive template
app.directive('myDir', function(){
return {
scope: {
myArr: "=",
},
restrict: 'EAC',
templateUrl: 'views/myHTML.html',
link: function(scope, element, attr) { }
};
});
And to use it
<div data-my-dir data-my-arr="arr">

Scope issue with multiple directives on same page

I have a directive that is used multiple times on the same page. The documentation has lead me to the following code:
<my-directive info="one"></my-directive>
<my-directive info="two"></my-directive>
.directive('myDirective', function() {
return {
restrict: 'E',
scope: {
itemInfo: '=info'
},
templateUrl: 'my_directive.html'
};
});
my_directive.html:
<div ng-repeat="item in itemInfo.items">
<div>{{item.name}}</div>
<div>{{item.value}}</div>
</div>
I can't get it to work, and I suspect it has to do with how I specify the scope in my directive and try to apply it in the ng-repeat. What am I missing?

Resources