I need to get append directive attribute value to templateUrl.
I tried several options however, templateUrl does not support $observe in it.
Therefore I tried below and tried to get "devicePath" value to templateUrl.
Nothing worked.
Here is my example.
<me-direct device-path="{{contentUrl}}" tmp-url="{{appTemplateUrl}}"></me-direct>
Directive js file
angular.module('meDevices').directive('medirect',medirect);
function medirect(){
return{
scope:{
devicePath:'#'
},
restrict: 'E',
controller: 'directCtrl',
link: function(scope, element, attrs) {
// some ode
attrs.$observe('devicePath', function(value){
console.log(value);
scope.url = value;
console.log(scope.url);
});
},
templateUrl: scope.url
}
}
Anyhow, this is not working since scope.url is not accessible from templateUrl. Any thoughts??
EDIT
But If I send attribute as this everything will work.
<me-direct device-path="some/common/url/to/view.html" tmp-url="{{appTemplateUrl}}"></me-direct>
Try this:::
angular.module('meDevices').directive('medirect',medirect);
function medirect(){
return{
restrict: 'E',
scope: {
base: '#baseUrl'
},
templateUrl: function(element, attrs) {
return "http://example.com/"+attrs['device-path']+attrs['tmp-url'];
}
}
}
Uses:
<me-direct device-path="{{contentUrl}}" tmp-url="{{appTemplateUrl}}"></me-direct>
Related
I am trying to pass 2 scope variables from controller into a custom directive and having problem in accessing both of them.Model is same for the directive and controller.
Here is the code:
Html:
<myDirective data="var1" item="var2"></myDirective>
Controller:
$scope.var1="abc";
$scope.var2="xyz";
Directive:
app.directive('myDirective', function () {
return {
restrict: 'E', //E = element, A = attribute, C = class, M = comment
scope: {
var1: '='
var2:'='
},
templateUrl: 'myTemplate.html',
link: function ($scope, element, attrs) {
}
}
});
TemplateUrl: myTemplate.html
<div>{{var1}}</div> // This works
<div>{{var2}}</div> // This doesn't works
Any idea how can I use both?
Make these changes in your code
<popover data="var1" item="var2"></popover>
JS
app.directive('popover', function () {
return {
restrict: 'E', //E = element, A = attribute, C = class, M = comment
scope: {
data: '=',
item: '='
},
templateUrl: 'myTemplate.html',
link: function (scope, element, attrs) {
console.log(scope.data, scope.item);
}
}
});
Change your template to match the names declared in the DDO.
<myDirective var1="var1" var2="var2"></myDirective>
Avoid using data as an attribute name. That is a reserved prefix that is stripped during normalization. For more information on attribute normilization, see AngularJS Developer Guide - Directive Normilization.
I wanna transfer a $scope.data to directive through its attribute in a Object, Can I achieve below format with any solution but not through separated attribute?
<custom-directive detail="{index:1, data: {{data}}}">
</custom-directive>
And the scope is set to below in directive
scope: {detail: "="}
One solution could be
return {
restrict: 'E',
require: 'ngModel',
scope: {
model: '=ngModel',
},
link: function(scope, element, attributes, ngModel) {
if (!ngModel) {
return;
}
console.log(scope.model); // your passed data
}
}
and then
<custom-directive ngModel="data"></custom-directive>
Now you will have your $scope.data passed to the directive inside scope.model. But note that, any change in scope.model in directive will reflect in $scope.data too.
To avoid that, you can simpley change ngModel.
return {
restrict: 'E',
scope: {
data: '=myData',
},
link: function(scope, element, attributes) {
console.log(scope.data); // your passed data
}
}
and then
<custom-directive my-data="data"></custom-directive>
You just write data only in your object, it will automatically resolves from your controller. Do as below:
HTML
<custom-directive detail="{index:1, data: data}">
</custom-directive>
Directive
myApp.directive('customDirective', function() {
return {
restrict:"AE",
scope:{
detail:"="
},
link:function(scope,ele,attrs) {
alert(JSON.stringify(scope.detail));
}
}
});
Fiddle Demo
You still have the solution to create your object in your controller :
$scope.detail = {index:1, data:$scope.data};
and to give it to your directive :
<custom-directive detail="detail"></custom-directive>
I've a custom directive called "mycomponent".
restrict: 'AE',
templateUrl: 'template.html',
scope:{
sTransactionType: '=transactionType',
sStorageVariable: '=storageVariable'
},
link: function(scope, element, attrs){
console.log("attrs.transactionType:: "+attrs.transactionType);
console.log("scope.sTransactionType:: "+scope.sTransactionType);
And markup as:
<my-component transaction-Type="FundTransfer" storage-Variable="FundTransferToday"></my-component>
Now, when I try to access the value of attributes transaction-Type and storage-Variable in link function of directive, it returns undefined.
Values can be accessed by attrs.transactionType but not able to get it with scope.sTransactionType.
I tried to change attribute name, scope varibale name.
How do I get custom directive attribute values in scope variables ?
Updated code:
var fundtransfer = angular.module("fundtransfer",['mydirectives']);
var controllers = {};
controllers.cntFundTransfer = function($scope, $rootScope){
}
var mydirectives = angular.module("mydirectives",['Constants']);
mydirectives.directive('myComponent', function($rootScope){
restrict: 'AE',
templateUrl: 'template.html',
scope:{
sTransactionType: '=transactionType',
sStorageVariable: '=storageVariable'
},
link: function(scope, element, attrs){
console.log("scope.sTransactionType:: "+scope.sTransactionType);
}
}
<my-component transaction-type="FundTransfer" storage-variable="FundTransferToday"></my-component>
Your attribute naming is wrong.
all should be in lowercase
try like this
<my-component transaction-type="FundTransfer" storage-variable="FundTransferToday"></my-component>
JS
restrict: 'AE',
templateUrl: 'template.html',
scope:{
sTransactionType: '=transactionType',
sStorageVariable: '=storageVariable'
},
link: function(scope, element, attrs){
console.log("scope.sTransactionType:: "+scope.sTransactionType);
}
as an angular newbie this is my problem
If I have two directives in HTML like this
<parent-dir param="par">
<child-dir></child-dir>
</parent-dir>
and in JS like this (in parent)
app.directive('parentDir', function(){
return {
restrict: 'E',
scope: {
param: '='
}
}
})
and in child
app.directive('childDir', function(){
return {
restrict: 'E',
require: '^parentDir',
controller: function($scope, $element){
<-- SHOULD I PUT WATCHER HERE -->
},
link: function(scope, element, attrs, parentdirCtrl){
<-- SHOULD I PUT WATCHER HERE -->
}
}
})
where in the child directive should I make an optional $watch in order to catch all changes to the param model?
Off course if I use $watch in the parent controller, all changes in the param are reflected in the parent directive but I can`t seem to find a way to pass this information to child directive.
You should place it inside the link function which have access of the parent controller using 4th parameter of link function parentdirCtrl. Actually you don't need to worry about the params variable because it uses = two way binding inside directive that does update the value in both parent controller scope & directive scope. Additionally you need define controller in your parentDir directive so that the scope of parentDir directive shared with the childDir.
Code
app.directive('childDir', function() {
return {
restrict: 'E',
require: '^parentDir',
template: '<div class="test">INner {{param}}</div>',
controller: function($scope, $element) {
},
link: function(scope, element, attrs, parentdirCtrl) {
scope.$watch('param', function(newVal, oldVal) {
console.log(newVal);
}) //true only if its object.
}
}
})
Demo Plunkr
I have 2 directives, one for searching and one for pagination. The pagination directive needs to access the search directive to find out what property we're currently searching by. When I load the page though, it throws an error saying Error: [$compile:ctreq] Controller 'search', required by directive 'pagination', can't be found!. However I have a controller setup in my search directive.
Here is my search directive:
angular.module('webappApp')
.directive('search', function ($route) {
return {
templateUrl: 'views/search.html',
restrict: 'E',
scope: {
searchOptions: '=',
action: '=',
currentProperty: '=',
currentValue: '='
},
controller: function($scope) {
$scope.searchBy = $scope.searchOptions[0].text;
$scope.searchByProperty = $scope.searchOptions[0].property;
$scope.setSearchBy = function(event, property, text) {
event.preventDefault();
$scope.searchBy = text;
$scope.searchByProperty = property;
};
$scope.search = function() {
$scope.searching = true;
$scope.currentProperty = $scope.searchByProperty;
$scope.currentValue = angular.element('#searchCriteria').val();
$scope.action($scope.searchByProperty, $scope.currentValue, function() {
$scope.searching = false;
});
};
$scope.reload = function() {
$route.reload();
};
}
};
});
Here is my pagination directive:
angular.module('webappApp')
.directive('pagination', function () {
return {
templateUrl: 'views/pagination.html',
restrict: 'E',
require: '^search',
scope: {
basePath: '#',
page: '=',
sort: '='
},
link: function(scope, element, attrs, searchCtrl) {
console.debug(searchCtrl);
scope.searchByProperty = searchCtrl.searchByProperty;
}
};
});
In order for one directive to use another's controller by use of require, it needs to either share the same element as the controller containing directive, or it has to be a child of it.
You can't use require in the way you have, where the elements are siblings.
Angular docs about directives, including require
If it doesn't make sense to rearrange the DOM in the way I've described, you should inject a service into both directives which contains the data/methods you wish to share between the two.
Note: you could also experiment with the $$nextSibling / $$prevSibling properties of the directives' scopes, but this would present only a very fragile solution
You cannot use require in directive like that, however , since the only thing you need to pass between directives is a string , just bind them to the same property in parent controller (it can be parent directive controller):
...
<div ng-app='app' ng-controller='MyCtrl as ctrl'>
<my-dir-one s1='ctrl.message'></my-dir-one>
<my-dir-two s2='ctrl.message'></my-dir-two>
and first directives:
app.directive('myDirOne', function ($route) {
return {
templateUrl: 'views/my-dir-one.html',
restrict: 'E',
scope: {
s1: '=',
second directive
app.directive('myDirTwo', function ($route) {
return {
templateUrl: 'views/my-dir-one.html',
restrict: 'E',
scope: {
s2: '=',