I have a directive as follows
<div ng-controller=prdController as prd>
<my-dir data=prd.data ng-click=stateChanged()></my-dir>
</div>
where prd.data is an object. In my directive I did the following
app.directive('myDir',function(){
return {
scope:{
data:'=data'
},
templateUrl: './templates/testtemplate.html',
controllerAs:'bd',
controller:function($scope,$attrs){
this.stateChanged = function (value) {
$attrs.data = { 'fd','sdfs'};
}
}
});
I am unable to modify the data value within the controller how do I proceed thanks in advance.
I think the problem could be in the way you trying to get data object in your controller.
You should try to get it by $scope.data. All directive inputs getting attached to your internal scope.
$attrs - is a hash object with key-value pairs of normalized attribute names and their corresponding attribute values. According to AngularJS docs.
Try this
var app = angular.module("myApp", []);
app.controller("prdController", function($scope) {
$scope.data = "krupesh";
$scope.stateChanged = function() {
$scope.data = "kotecha";
}
});
app.directive('myDir', function() {
return {
restrict: 'E',
template: "<div>{{data}}</div>"
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller=prdController as prd>
<my-dir data="prd.data" ng-click=stateChanged()></my-dir>
</div>
Related
My directive has separate controller in js file, which has a scope variable parameterDatabase which need to be populated from calling page. I am unable to find the way to pass value to it.
<body ng-app="testAPP" ng-controller="ctl">
Directive Here
<my-cust parameterDATABASE="dt"></my-cust>
<script >
APP = angular.module("testAPP",['schedule']);
APP.controller("ctl",function($scope)
{
$scope.dt = {date:"02-03-2017",sDay:"Thu",sTime:"01:00"};
}) // end of controller
APP.directive("myCust",function()
{
return{
scope:{
parameterDATABASE:'='
},
controller:"scheduleCtrl",
templateUrl:"templateForDirective.html"
}
})
</script>
The scheduleCtrl has a variable parameterDATABASE too.
part of Directive's contrller
var APP = angular.module('schedule',[]);
APP.controller('scheduleCtrl',function($scope,$filter)
{ $scope.parameterDATABASE=[]; // This is the variable I want to populate
..............
1) According to some angular naming conventions, the attribute name of a directive should be converted into camelCase.
So, parameterDATABASE in the html Directive should be parameter-database
So, inside the directive, you should use that as,
scope: {
parameterDatabase: '='
}
So, parameterDatabase maps to ==> parameter-database
2) you can also use, parameterdatabase directly in both places without capitalizing.
Eg: parameter-database="dt" in html directive
scope: {
parameterdatabase: '='
}
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="myApp" ng-controller="ctl">
<isolate-scope-with-controller parameter-database="dt" add="addCustomer()"></isolate-scope-with-controller>
<script>
var app = angular.module("myApp", []);
app.controller("ctl",function($scope)
{
$scope.dt = {date:"02-03-2017",sDay:"Thu",sTime:"01:00"};
}) // end of
app.directive('isolateScopeWithController', function () {
var controller = ['$scope', function ($scope) {
console.log($scope.parameterDatabase)
}],
template = '<h1>I am from directive controller</h1><br><h2>{{parameterDatabase}}</h2>';
return {
restrict: 'EA', //Default in 1.3+
scope: {
parameterDatabase: '='
},
controller: controller,
template: template
};
});
</script>
</body>
</html>
PLEASE RUN THE ABOVE SNIPPET
Here is a working DEMO
I am a bit struggling with infinite scroll in angular. I have one object array where all items are stored in. This object is part of directive controller.
Now when I am trying to implement infinite scroll I use separate directive to calculate offsets. I would like to access from this scroll directive variable from the other directive where object array is defined.
How can I do this? What would be the easiest way here? I am searching for week and can't find anything easy enough to implement to my solution.
Thank you
You could either use the directive's require property to get the $scope of another directive's controller, or use the parent controller of the directives to pass in a shared value. Here's an example using require (live demo).
<div ng-app="myApp">
<foo></foo>
<bar></bar>
</div>
angular.module('myApp', [])
.directive('foo', function() {
return {
controller: function($scope) {
$scope.foo = 123;
}
};
})
.directive('bar', function() {
return {
require: '^foo',
controller: function($scope) {
console.log($scope.foo);
}
};
})
;
The timing for this next example may not be what you want. They are sharing the same variable, but changes to $scope in the first directive's controller won't be applied until after the second directive's controller has already run. (live demo).
<div ng-app="myApp" ng-controller="MyCtrl">
{{sharedValue}}
<foo shared-value="sharedValue"></foo>
<bar shared-value="sharedValue"></bar>
</div>
angular.module('myApp', [])
.controller('MyCtrl', function($scope) {
$scope.sharedValue = 'abc';
})
.directive('foo', function() {
return {
scope: {
sharedValue: "="
},
controller: function($scope) {
console.log($scope.sharedValue); // abc
$scope.sharedValue = 123;
}
};
})
.directive('bar', function() {
return {
scope: {
sharedValue: '='
},
controller: function($scope) {
console.log($scope.sharedValue); // still abc, will update later
}
};
})
;
I've created a custom directive which contains a button. This button calls a method from parent scope specified by 'callback' attribute.
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>Simple directive</title>
<script src="js/lib/angular/angular.js"></script>
<script type="text/javascript">
var app = angular.module('app', []);
app.controller('TestController', function($scope) {
$scope.doSomething = function(param) {
alert('Something called with: ' + param);
}
})
app.directive('myDirective', function() {
var ret = {
restrict: 'E',
scope: {
user: '#',
callback: '&' // bound a function from the scope
},
template: '<div>Hello {{user}}<button ng-show="hasCallback()" ng-click="callback({userData: user})">Callback</button>',
controller: function($scope) {
$scope.hasCallback2 = function() {
var t = typeof $scope.callback;
return t == 'function';
}
$scope.hasCallback = function() {
return angular.isDefined($scope.callback);
}
}
};
return ret;
});
</script>
</head>
<body ng-controller="TestController">
<my-directive user="cat" callback="doSomething(userData)"></my-directive>
<my-directive user="dog" callback="doSomething(userData)"></my-directive>
<my-directive user="pig"></my-directive>
</body>
</html>
My question is:
How can I control visibility of button inside template? I'd like to hide it if callback attribute not specified in custom tag (see 3rd my-directive tag).
When I check typeof of callback, I always get 'function' and angular.isDefined(...) also returns true.
Using '&?' returns undefined if the attribute has not been set.
'&' = callback function is defined always.
'&?' = callback function is defined only when attribute is defined in html template.
bindToController: {
callback: '&?'
},
controller: function() {
if (this.callback === undefined) {
// attribute "callback" was not defined
}
}
Note: Works in Angular 1.4.8. I'm not sure if it works in older versions.
Looking at angularjs source code, I see this:
case '&':
parentGet = $parse(attrs[attrName]);
isolateScope[scopeName] = function(locals) {
return parentGet(scope, locals);
};
break;
The parentGet is the bound function expression. Unfortunately, this is a local variable which is only available to the function assigned to isolateScope[scopeName] via closure.
Instead of trying to find a way to get that variable, a simple solution is just to check the attrs. Try:
link: function(scope,elem,attrs) {
scope.hasCallback = function() {
return angular.isDefined(attrs.callback);
}
}
DEMO
I have created one directive in Angularjs in which I need to use callBackMethod, so that I can call Controller's Function.
Controller's function is called.But Controller's Function is returning some value.I want to get that value in callback function.How to achieve that?
Below is my code for Directive
.directive('abcOption', function($compile) {
return {
restrict : 'A',
template : '<div class="filter-content"></div>',
replace : true,
scope : {
callBackMethod:'&getDisplayName'
},link: function(scope,element,attrs)
{
scope.getDataName =function(dataId)
{
scope.callBackMethod(dataId);
};
}
};
});
Below Code is for Controller function
$scope.getDisplayName = function(columnName) {
return 'abc';
};
It's small snippet of the code. Controller function is called but I am not getting return value in directive function. I am getting undefined in console log if I log scope.callBackMethod(dataId);
How to get return value using callBackMethod in Directive?
While calling the controller's function from inside a directive with an isolate scope, you need to pass an object:
HTML
<div ng-app="myApp" ng-controller="ctrl">
<div abc-option get-display-name="getDisplayName(columnName)"></div>
</div>
JS
var app = angular.module('myApp', []);
function ctrl($scope){
$scope.getDisplayName = function(columnName) {
return 'abc';
};
}
app.directive('abcOption', function($compile,$timeout) {
return {
restrict : 'A',
template : '<div class="filter-content">abc</div>',
replace : true,
scope : {
callBackMethod:'&getDisplayName'
},
link: function(scope,element,attrs){
/* send an object to the function */
console.log(scope.callBackMethod({columnName:"hurray"}));
}
};
});
Fiddle
The answer from CodeHater works but is (just a little) confusing. So I updated it to make it easier to understand
HTML
<div ng-app="myApp" ng-controller="ctrl">
{{returnVal}}
<div abc-option callback="setDisplayNameFn(mustBeTheSame)"></div>
</div>
JS
var app = angular.module('myApp', []);
function ctrl($scope){
$scope.setDisplayNameFn = function(whatever) {
$scope.returnVal= whatever;
};
}
app.directive('abcOption', function($compile,$timeout) {
return {
restrict : 'A',
template : '<div class="filter-content"><b>directive html<b></div>',
replace : true,
scope : {
callBackMethod:'&callback'
},
link: function(scope,element,attrs){
/* send an object to the function */
console.log(scope.callBackMethod({mustBeTheSame:"value from directive"}));
}
};
});
updated fiddle
I'm trying to create a dynamic directive that will receive his binding options from attributes.
This is my controller view:
<div ng-controller="OtCtrl">
<div ng-include src="'/client/views/openTradeView.html'"></div>
</div>
my View:
<div>
{{name}}
<div swings binding="Risk" title="Risk"></div>
<div swings binding="Amount" title="Amount"></div>
</div>
This is my directive View:
<div>
{{title}}
-
{{amount}}
+
</div>
This is my directive:
app.directive("swings", function () {
return {
replace: true,
scope: {
title : '#title',
amount: '=binding',
extra: '=bindingExtra'
},
resctrict: "A",
controller: function($scope){
$scope.minus = function (event, binding) {
$scope.amount -= 1;
console.log(binding)
}
$scope.plus = function (event) {
$scope.amount += 1;
}
},
templateUrl: '/client/views/swingsDirectiveView.html'
}
});
And finally my Controller:
app.controller("OtCtrl", ['$scope', function ($scope) {
$scope.Amount = 400;
$scope.Risk = 100;
setInterval(function(){
console.log($scope.Risk)
},2000);
}]);
I know that when I use ng-view, angularjs creates new scope. My issue that when I click plus or minus, the amount in the directive updates but the Risk model in the controller not, but on first load directive takes the risk init value and set the amount.
How can I fix this issue.
Thanks
I would suggest creating a model property in your controller like so:
app.controller("OtCtrl", ['$scope', function($scope) {
$scope.model = {
Amount: 400,
Risk: 100
}
}]);
Then, bind it to your directive via:
<div swings binding="model.Risk" title="model.Risk"></div>
What is likely happening is that scope inheritance is creating a copy of Amount and Risk (since they're primitives); whereas creating an object like this causes the reference to get copied, meaning the scope hierarchy shares the same data.