AngularJs directive to access the parent scope - angularjs

I want to show the password fields based upon the condition. Also I want to validate the password fields if it is shown. For this I have to create a directive. But the directive creates new scope for the template and does not access the parent scope to validate the password fields. How could I achieve this?

You can send it through the DOM.
Send the data from the controller's scope and send that as an attribute to the directive you are creating.
angular.module('App', [])
.controller('Controller', ['$scope', function($scope) {
$scope.data = ....;
}])
.directive('myDirective', function() {
return {
scope: { info = '=info' },
template: '<div ng-repeat="i in info"> Name: {{i.name}} Password: {{i.password}}</div>',
link: ...
}
});
<html>
<body ng-app="App">
<div ng-controller="Controller">
<my-directive info="data"></my-directive>
</div>
</body>
</html>

Related

How to have control over an input field from a template of a directive in AngularJs

My directive contains in its template a simple input field, and I'm lookin for a solution to have control on that input field by using ngModel, but I don't know how to do.
Template:
<input name="myInput" ng-model="myInput" type="text"/>
Directive JS:
app.directive('ghPca', ['$http', '$q', function($http, $q) {
return {
restrict : 'E',
templateUrl : '/javascripts/ang/directives/pca/gh-pca-template.html',
scope : {
isEnable : '='
},
link : function($scope, $el, $attrs){
//how can I manage/control the input of THIS directive?
}
}
}]);
Directive use:
<gh-pca></gh-pca>
I don't know what to set up (write) in the controller/link to bind the input. Any suggestion?
SOLUTION
The solution I was looking for it's like that one here below
app.directive('ghPca', ['$http', '$q', function($http, $q) {
return {
restrict : 'E',
templateUrl : '/javascripts/ang/directives/pca/gh-pca-template.html',
scope : {
isEnable : '='
},
link : function($scope, $el, $attrs){
//how can I manage/control the input of THIS directive?
},
controller : function($scope) {
//here I can have control on my **$scope.myInput**
}
}
}]);
The very basic way in which you can understand that how to have control over an input field is :-
<html ng-app="myApp">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
</head>
<body>
<div ng-controller="MainCtrl">
<input name="myInput" ng-model="myInput" type="text"/><button type="submit" ng-click='sub()'>Submit</button>
{{data}}
</div>
<script>
angular.module('myApp',[])
.controller('MainCtrl',['$scope',function($scope){
$scope.sub = function(){
$scope.data = 'Hi'+ ' ' +$scope.myInput;
}
}]);
</script>
</body>
</html>
So in your controller you need to define some function that will be performed,what I have done in this example by defining the scope of ng-model I have assigned it to another scope called data and printed it with a Hi quote,this is the very basic way,this will give you an idea how to play around with it.
Hope I made you understand this.
Thanks!

Creating directive AngularJS without $scope

I´m learning AngularJS. Now I´m trying the directives. I created a directive but I can´t make it work. I can do it with $scope, but I want to know HOW to do it without it.
The code:
<div ng-app="myApp" ng-controller="controls">
<div the-name></div>
</div>
<script src="angular.js"></script>
<script>
var modu = angular.module("myApp", []);
modu.controller("controls", [function() {
var self = this;
self.user = {
name : "Pedro",
lastname: "Delgado"
};
}]);
modu.directive("theName", [function() {
return {
template: 'Name: {{user.name}}'
};
}]);
</script>
An the RESULT is:
Name:
And I want:
Name: Pedro
Anyone can help me?
Thanks a lot!
It's called controller-as syntax. You need to create an alias to controller in the template:
<div ng-app="myApp" ng-controller="controls as ctrl">
<div the-name></div>
</div>
and then in directive template use {{ctrl.user.name}}.
But ideally, you isolate the scope of the directive, because you don't want it to know about its surroundings and what controllerAs alias is used.
This version of your directive will be much more reusable:
modu.directive("theName", [function() {
return {
scope: {
user: '='
},
template: 'Name: {{user.name}}'
};
}]);
and usage is:
<div ng-app="myApp" ng-controller="controls as ctrl">
<div the-name user="ctrl.user"></div>
</div>
So in this case, directive (and template) doesn't know anything about environment it's used (about controller prefix, etc), it only cares that proper user object was passed in it. This is the point of isolated scope.

Angular directive controller scope visibility

Question
Why isn't monkey and selected visible to the template?
Plunk
http://plnkr.co/edit/djS0KWyfJNKD0tfZ0IiV?p=preview
Code
<head>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.3/angular.js"></script>
<script type="text/javascript">
angular
.module('toruSelect', [])
.directive('toruSelect', function () {
return {
restrict: 'AE', // Allow usage as A - attribute, E - element
scope: { // Isolated scope
selected: '=' // Bi-directional binding to selected attribute,
},
controller: ['$scope', function ($scope) {
$scope.monkey = 'MONKEY';
console.log('toruSelect.controller.$scope', $scope);
}]
}
});
var app = angular.module('app', ['toruSelect']);
app.controller('AppCtrl', function($scope) {
$scope.val = 'initial';
$scope.appData = 'App data';
});
</script>
</head>
<body ng-controller="AppCtrl">
<h1>Directives and scopes..</h1>
<div toru-select selected="val">
<div style="color: red">RESULT: toruSelect.controller.monkey: {{monkey}}</div>
<div>EXPECTED: toruSelect.controller.monkey: MONKEY</div>
<div style="color: red">RESULT: toruSelect.controller.selected: {{selected}}</div>
<div>EXPECTED: toruSelect.controller.selected: initial</div>
</div>
</body>
Result
Directives and scopes..
RESULT: toruSelect.controller.monkey:
EXPECTED: toruSelect.controller.monkey: MONKEY
RESULT: toruSelect.controller.selected:
EXPECTED: toruSelect.controller.selected: initial
As you pointed it out on the comment of your directive, it has an isolated scope, so that value attached with monkey key is available on directive scope, not on controller one.
For selected, you have to display {{val}} and not {{selected}} as it's the variable concerned by the bi-directional binding on the directive scope.

AngularJS: Access formController of a form placed inside transcluded directive from parent controller

I've created a simple "modal dialog" directive, which uses transclude. I would like to place a form () inside the "modal dialog" directive. I would expect that formController of a form placed inside the directive, is going to be accessible in parent controller's scope, however it isn't. Take a look at the following fiddle, please: http://jsfiddle.net/milmly/f2WMT/1/
Complete code:
<!DOCTYPE html>
<html>
<head>
<title>AngJS test</title>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/foundation/4.0.9/css/foundation.min.css">
<style>
.reveal-modal {
display: block;
visibility: visible;
}
</style>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module('app', []);
app.controller('appCtrl', function ($scope) {
$scope.model = {
id: 1, name: 'John'
};
$scope.modal = {
show: false
};
});
app.directive('modal', function () {
return {
scope: {
show: '='
},
transclude: true,
replace: true,
template: '<div class="reveal-modal small" ng-show="show"><div class="panel" ng-transclude></div></div>'
}
});
</script>
</head>
<body ng-app="app">
<div ng-controller="appCtrl">
<div class="panel">
Id: {{ model.id }}<br>
Name: {{ model.name }}<br>
Controller formController: {{ form }}<br>
Directive formController: {{ myForm }}<br>
</div>
<form name="form" class="panel">
<input type="text" ng-model="model.name">
</form>
<a ng-click="modal.show=!modal.show">toggle dialog</a>
<div modal show="modal.show">
<form name="myForm">
<input type="text" ng-model="model.name">
</form>
</div>
</div>
</body>
</html>
So my question is how to access or is it possible to access directive's formController from parent controller?
Thank you for answers.
-Milan
Because you are using transclude, the directive will create a child transcluded scope. There is no easy path from the controller scope (003) to the directive's transcluded scope (005):
(The hard/not recommended path is to go via private property $$childHead on the controller scope, find the isolate scope, then use $$nextSibling to get to the transcluded scope.)
Update:
From insights from this answer, I think we can get the formController inside the directive, then use = to get it to the parent.
scope: { show: '=', formCtrl: '=' },
...
link: function(scope, element) {
var input1 = element.find('input').eq(0);
scope.formCtrl = input1.controller('form');
}
HTML:
<div modal show="modal.show" form-ctrl="formCtrl">
Fiddle
Here is my solution:
I create such method in parent controller :
$scope.saveForm = function(form) {
$scope.myForm = form;
};
Then I call it in transcluded content:
<my-directive>
<form name="myForm">
<div ng-init="saveForm(myForm)"></div>
</form>
</my-directive>
After creating directive instance i have form controller instance in parent scope.

ng-click attribute on angularjs directive

I think it should be easy to use the well known angular attributes on a directive out of the box.
For example if the name of my directive is myDirective I would like to use it this way:
<div ng-controller="myController">
<my-directive ng-click="doSomething()"><my-directive>
</div>
instead of needing to define a custom click attribute (onClick) as in the example below
<div ng-controller="myController">
<my-directive on-click="doSomething()"><my-directive>
</div>
It seems that ng-click can work, but then you need to specify ng-controller on the directive tag too which I don't want. I want to define the controller on a surrounding div
Is it possible to use ng-click on a directive together with a controller defined on a parent html element?
Here is updated code. Maybe is this what you were looking for.
Html:
<div data-ng-app="myApp">
<div data-ng-controller="MyController">
<my-directive data-ng-click="myFirstFunction('Hallo')"></my-directive>
<my-directive data-ng-click="mySecondFunction('Hi')"></my-directive>
</div>
</div>
Angular:
var app = angular.module('myApp', []);
app.directive('myDirective', function(){
return {
restrict: 'EA',
replace: true,
scope: {
eventHandler: '&ngClick'
},
template: '<div id="holder"><button data-ng-click="eventHandler()">Call own function</button></div>'
};
});
app.controller('MyController', ['$scope', function($scope) {
$scope.myFirstFunction = function(msg) {
alert(msg + '!!! first function call!');
};
$scope.mySecondFunction = function(msg) {
alert(msg + '!!! second function call!');
};
}]);
Edit
Check solution that I made in jsFiddler is that what you were looking for?
http://jsfiddle.net/migontech/3QRDt/1/

Resources