Angularjs directive set scope var in directive and access in controller - angularjs

Hi I am working on angularjs. I am facing an issue in directive.
I have set the scope.user.name="amin shah" on link/click event
and want to access this in controller how is this possible?
var dataSourceDirective = angular.module('mydirective', []);
dataSourceDirective.directive('dir', function () {
return {
restrict: 'C',
scope: true,
link: function ($scope, element, attrs) {
element.bind('click', function () {
$scope.user.name ="amin shah";
$scope.$apply();
$('.sourceType_panel').hide();
$('#sourceType_1_panel').show();
});
}
}
});
controller code
$scope.demo = function () {
console.log($scope.user);`
},

You need to create Isolated scope in your directive.
The given controller should be parent of this directive.
var dataSourceDirective = angular.module('mydirective', []);
dataSourceDirective.directive('dir', function () {
return {
restrict: 'C',
scope: {user:"=user"},
link: function ($scope, element, attrs) {
element.bind('click', function () {
$scope.user.name ="amin shah";
});
}
}
});
In html :
<div ng-copntroller='yourCtrl'>
<dir user="user"></dir>
</div>
In Controller you should initialize the user.
OR
you use $broadcast & $emit if the parent is controller.
Withing link function of directive you can use $rootScope.$emit('user_name_update',user);
And in the controller you can listen this event
$scope.$on('user_name_update',function(data){
console.log(user) // its should give your updated `user` object
})

First of all you should correct your link method and I think you shouldn't need child sope at there. So you should delete your scope bind in directive too. You can reach parent scope with link method.
app.directive('dir', function () {
return {
restrict: 'E',
link: function (scope, element, attrs) {
element.bind('click', function () {
scope.user.name ="amin shah";
scope.$apply();
});
}
}
});
and in your controller you can define scope variable like that:
app.controller('MainCtrl', function($scope) {
$scope.user = {
name: ''
}
});
also you should add this directive to HTML :
<dir>Element</dir>
<p>{{user.name}}</p>
here is the working plunkr you should click Element than you can see your name from directive but in parent scope
https://plnkr.co/edit/umTdfukZ22hARoLjxdL3?p=preview

Related

Get data back from angular directive

I've created a directive which I called my-tree, and I'm calling this directive from a view exemple-tree-view.html as following:
<my-tree ng-model="sampleTreeView.listNoeuds" ... />
this view's controller called sampleTreeView.
In my directive's link function I have a function that returns some data, which I affect to scope variable declared in the directive's controller, as following :
function linkFn(scope, element, attrs) {
//some code
scope.createNode = function ($event) {
var sel = $(element).jstree(true).create_node($($event.currentTarget)[0].closest('.jstree-node').id);
if (sel) {
$(element).jstree(true).edit(sel, '', function (node, success, cancelled) {
scope.treeActionsResult.createdNode = node;
});
}
};
//some code
}
My question is how can I get the scope.treeActionsResult.createdNode value in the sampleTreeView controller, since it's the controller for the exemple-tree-view.html where I call my directive.
You can use shared scope between the directive and controller by removing the scope property
like in this example:
MyApp.directive('studentDirective', function () {
return {
template: "{{student.name}} is {{student.age}} years old !!",
replace: true,
restrict: 'E',
controller: function ($scope) {
console.log($scope);
}
}
});
Still you have the $scope object, but in this case the scope object is shared with parent controller's scope.
You can read more about it fron the following link
Understanding Scope in AngularJs Custom Directive
If you don't create isolated scope for your directive then you can access directive scope values from your controller. like bellow
your controller and directive:
app.controller('MainCtrl', function($scope) {
$scope.value = 1;
});
app.directive('myTree', function() {
return {
restrict: 'AE',
link: function(scope, element, attrs) {
scope.values = {};
scope.values.price = 1234;
}
};
});
then use in your html like:
<body ng-controller="MainCtrl">
<p>value {{values.price}}</p>
<my-tree att="{{attValue}}"></my-tree>
</body>
here values.price shown from directive in MainCtrl

Typeerror - Not a function in angular directive

I have defined a custom click directive as below:
(function() {
'use strict';
angular.module('myApp.core')
.directive('customClick', customClick);
customClick.$inject = ['$rootScope'];
function customClick() {
return {
restrict: 'A',
/*scope: {
customClick: '&'
},*/
link: function(scope, element, attrs){
$(element).on('click', function(e) {
scope.$apply(function() {
console.log("Hello..customClick..");
scope.customClick();
});
});
}
};
}
})();
And I get the following error on this;
Error logged by WDPR Angular Error handler service {xx.."stacktrace":"TypeError: a.customClick is not a function","cause":"unknown cause"}(anonymous function)bowerComponents.js:5745
How can I resolve this? If I add scope with '&' I get demanding isolated scope. Hence how to resolve it?
If I remove - scope.customClick();, it does not show anything on second html for custom-click, it has impact on only 1 html, and its controller. I want to use it in multiple controller + html.
customClick is a function on the directive itself. It is not a function on the scope. That's why the error has occurred.
link is used to manipulate dom/add event handlers on elements, which you have rightly done with element.bind('click', function() {
Whenever click occurs, the function binded to click automatically gets invoked. There is no need of watch and the invoking statement.
Your link can just be
link: function(scope, element){
element.bind('click', function() {
console.log("Hello..customClick..");
});
}
As you have used camel case in naming the directive, exercise caution in its usage in template.
You can use it as <p custom-click>hi</p>
I would recommend you to avoid using jQuery in angular apps. Try following
angular.module('newEngagementUI.core')
.directive('customClick', customClick);
customClick.$inject = ['$rootScope'];
function customClick() {
return {
restrict: 'A',
scope: {
customClick: '&'
},
link: function(scope, element, attrs){
element.bind('click', function () {
scope.customClick();
})
}
};
}
In your template:
<div custom-click="clickFunction"></div>
And your template controller should be like:
angular.module('myApp', []).controller(['$scope', function ($scope) {
$scope.clickFunction = function () {
alert('function passed');
}
}])
Working fiddle here: https://jsfiddle.net/xSaber/sbqavcnb/1/

calling a controller function from a link in a directive

I'm writing an Angular 1.5.0-beta2 project.
I want to call a controller function from the link property of the returned object.
which means...
angular.module('myalcoholist').directive("ngFileSelect",function() {
return {
controller: 'AddCoctailController',
controllerAs: 'addCocktail',
link: function ($scope, el) {
el.bind("change", function (e) {
var file = (e.srcElement || e.target).files[0];
/*THIS DOES NOT WORK */ addCocktail.getFile(file);
})
}
}
});
as you can see here i'm trying to run a controller function called getFile.
is it even possible ?
If you use a angular >= 1.3, use bindToController option
angular.module('myalcoholist').directive("ngFileSelect",function() {
return {
controller: 'AddCoctailController',
controllerAs: 'addCocktail',
bindToController: true,
link: function (scope, el) {
el.bind("change", function (e) {
var file = (e.srcElement || e.target).files[0];
scope.addCocktail.getFile(file);
});
}
}
});
codepen: http://codepen.io/gpincheiraa/pen/VeYxGN
Adding to Chris's answer above - link has several parameters (scope, element, attrs, controller). You can access the attached controllers functions doing the following:
link: function(scope, elem, attrs, ctrl){
ctrl.func_to_call();
}
Controller is to populate $scope and link is running after controller so you can just access whatever is on your scope in link function.
angular.module('app', [])
.directive('tstDrv', function () {
return {
restrict: 'E',
template: '<div>{{hello}}</div>',
link: function (scope) {
console.log(scope.hello);
scope.hello = "hello again";
},
controller: function ($scope) {
$scope.hello = 'tst';
}
}
})
Also this SO question is related Angular: calling controller function inside a directive link function using &
If one wants to access a scope property that has been defined outside of current directive scope it all depends on scope property of 'Domain Definition Object'.
Ref. https://github.com/angular/angular.js/wiki/Understanding-Scopes#javascript-prototypal-inheritance

Bind directive scope without having controller scope in Angular Js?

html :
<div ng-app="appMod">
<div task-info>{ { data.name } }</div>
</div>
script :
var appmod = angular.module('appMod', []);
appmod.directive("taskInfo", function () {
return {
restrict: 'A',
scope: {},
link: function ($scope, $element, attr) {
$scope.taskdat = '{"name":"Task name","status":"Completed"}';
$scope.data = JSON.parse($scope.taskdat);
scope = $scope; //scope data
},
};
});
is it possible to bind directive scope without having controller scope in Angular Js? If yes, please give me some solution examples.
You don't need a controller scope for writing a directive , see this fiddle.
Here, there is no controller scope, and the value hero is bound within the directive as:
myApp.directive('myDirective', function() {
return {
restrict: 'EAC',
link: function($scope, element, attrs, controller) {
var controllerOptions, options;
$scope.hero='superhero'
}
};
});
Works fine :)
Also the example you provided is similar, but you just need to remove scope from returned JSON object(from directive), as it is being defined as $scope inside the link fucntion.
see : http://jsfiddle.net/bg0L80Lx/
controller option ?
.directive('mydirective', function() {
return {
restrict: 'A', // always required
//controller: 'SomeController'
template:'<b>{{status}}</b>',
controller:'YourCtrl'
}
})

Angular js. Assign Controller with Directive

I try to connect the controller with the directive in Angular.
Here html
<div ng-controller="MyCtrl">
<div id='bbb' my-num>Click Me!</div>
</div>
I use the MyCtrl controller where I define tegid and mytitle.
MainControl.controller('MyCtrl', ['$scope',
function($scope) {
$scope.tegid = '';
$scope.mytitle = 'aaa' + tegid;
}]);
Also I have the directive myNum in which when hover at I receive 'id' and I change its contents
MainDirectives.directive('myNum', function () {
return {
link: function ($scope, element, attrs) {
element.bind('mouseenter', function () {
tegid = element.attr('id');
element.html(mytitle);
});
}
};
});
Problem in that I can't connect the directive and the controller.
Prompt, please, how to transfer tegid to the MyCtrl controller?
Why it is impossible to transfer mytitle to the directive myNum?
You need to pass tegid and mytitle from the controller socpe to the directive scope, by doing as following:
Using isolated scope
Directive:
directive('myNum', function () {
return {
scope: {
id: '=',
title: '='
},
link: function ($scope, element, attrs) {
element.bind('mouseenter', function () {
// scope.id and scope.title are shared with parent scope via HTML bindings
tegid = scope.id;
element.html(scope.title);
});
}
};
Html:
<div id='tegid' title="nytitle" my-num>Click Me!</div>
This will create an isolate scope for your directive and is cleaner. However if you don't intend to reuse the directive elsewhere, you can just rely on scope inheritance, which means you'll have access to the parent scope properties:
Using scope inheritance
Directive:
directive('myNum', function () {
return {
link: function ($scope, element, attrs) {
element.bind('mouseenter', function () {
// scope.teif and scope.mytitle come from the parent scope
tegid = scope.teid;
element.html(scope.mytitle);
});
}
};
Html:
<div my-num>Click Me!</div>
Reference the $scope that is passed thru the link function:
link: function ($scope, element, attrs) {
element.bind('mouseenter', function () {
$scope.tegid = element.attr('id');
element.html($scope.mytitle);
});
}

Resources