I have a page with two directives.
1. Directive that lists items , these items have a property on them call url
2. a directive on the same page that accepts url and displays it
What I want to do is, when the user clicks on one of the items in the first directive, to send that item.url to the 2nd directive as a parameter ?
What is the best practices for this scenario ?
Few ways to achieve this:
Common Parent Scope Property
Specifically the parent controller encompassing both of your directives has a property for storing the selected URL.
Then this property is passed into both of your child directives.
e.g.
<parent>
<directive-one data-selected-url="selectedUrl"></directive-one>
<directive-two data-url-to-display="selectedUrl"></directive-two>
</parent>
Broadcast Events
Have directive one broadcast an event on a scope that is shared by both directives.
e.g.
in directive one:
$scope.$broadcast('urlSelected', selectedUrl);
in directive two:
$scope.$on('urlSelected', function(event, selectedUrl) { ... });
NOTE: as I mentioned the scope needs to be a shared scope between the two directives, as broadcast sends the event DOWN the scope chain ($emit sends it up).
Accessing Parent Controllers
You could store the selected Url in a parent directive and have both children require that directive. They would then both be able to set/get the property from the parent directive.
e.g. in the child directives:
require: 'parentDirective'
link: function (scope, element, attrs, parentCtrl) {...}
Related
How can I access scope value in first directive controller to second directive controller.
So What I mean is if I have $scope.Hello= "Hello"; in first directive I want to access this in my second directive controller.
How can I do that. I tried with broadcast but I know that only between parent and child access. Here my scenario is child and child access.
In the link of first directive, call 2nd directive and pass it as attribute.
link: function (scope, element, attrs) {
angular.element(document.body).append($compile('<my2ndDirectivehello="' + scope.hello+'"></my2ndDirective'>
};
In my angular app I've got a parent directive, say a list of some sort, that contains many child directives, say items.
I'd like to be able to call a certain method on the children from the parent. I know in advance what children I'd be calling (by an input of start and end index of the items list). Therefore I wish to avoid using broadcast, as I don't want to call all children but just a selected few.
Both the children and the parent have their own isolated scopes.
How can I achieve this?
Try to create controllers for your parent directive. That is accessible for your children directives, it's some kind of shared functions for your children directives. Then you can register a function which can add new functions to the parent controllers that u can later execute.
Let me show you with a quick example (maybe it won't work with copy-paste, its just the theory how should it look like)
//parent directive's controller function
function ParentControllerFunction(){
this.arrayOfChildFuncions = [];
}
//your child directive's link function
require: '^ParentControllerFunction'
link: function(scope, element, attr, ctrl){
function myLittleFunction(){
//hhere is your function that you can call
}
ctrl.arrayOfChildFuncions.push(myLittleFunction);
}
Then later on you can execute your functions depending on which one do you want to:
//executes the 3rd directive's function with the parameter 'hello'
arrayOfChildFuncions[3]('hello')
you can use $index in order to get the desired directive from ng-repeat, and then call your function.
https://docs.angularjs.org/api/ng/directive/ngRepeat
I've a scenario:
1) user clicks on a link and a request is sent (from a controller) to the backend to create a DB record.
2) the response is returned as a promise in the controller and am able to see the data from DB.
3) The link clicked in #1 opens a directive (element directive btw) which displays a popup window.
4) The controller and the directive are not related, but i need to show the data in the popup (opened by the directive).
I'm new to AJS and my knowledge is smattering. Should i use service/rootscope? to send data the promise to the directive.
It sounds like your main question is how to get data into a directive. I can think of two ways (there are probably more).
You can use the directive's isolate scope to pass in information from your controller. You have few options for binding to this scope (see the scope section of $compile). = for two-way binding or & for an expression binding &. This might look something like
app.directive('myDirective', [
function() {
restrict: 'E',
templateUrl: 'some template url',
scope: {
databaseRow: '='
}
}
])
Which would be used like this in the HTML
<my-directive database-row="controllerResult"></my-directive>
You can also create and inject a service into your directive, and move the DB logic into the directive. You could have the controller broadcast an event or change a variable to trigger the directive, or even just have some visible element within the directive respond to a mouse click.
I tried to find linking of multiple controllers to a single custom directive, but no solution. Is this possible to achieve or not. Can anybody please tell me.
Requirement: I created a directive with a controller. I'm calling that directive in a page and the page is having its own controller. Now the page controller have a couple of functions. I'm using a template with some events. Those events are implemented in the page controller (parent controller). So those functions are not firing.
<div ng-controller="controllername">
<myDirective name-"name" event="doSomeEvent(params)"/>
In the controller i have a couple of functions like
app.controller("controllername",['$scope','function($scope))
{
$scope.functionName = function()
{
alert(1);
}]
}
This function is linked to the directive template. How to make this event fired?
my guess is that your directive has got an isolated scope.
meaning you have in your directive definition a line with scope: {}.
that makes it isolated and it can't see the parent scope (meaning that controller 'controllername' you have there)
remove the scope definition from the directive (remove the scope: {}) and you will have access to the parent scope.
and you will be able to use those function as if they were in the directive scope.
I have a MainController and a nested Directive. I'm looking at this example to see how the communication works between controllers and directive, but mine doesn't seems to work.
Basically, I want to call a main controller scope function from a custom directive (button empty cart). See the plunkr example below.
Plukr: http://plnkr.co/edit/82STLkKxBK6htTnmnqlu?p=preview
Whenever I do console.log(scope.$apply("emptyCart()")), it's undefined for some reason.
Note: I'm trying to avoid $rootScope.broadcast as much as possible...
You're using isolate scope for the parent directive, so the child directive does not have access to the scope of the controller.
In order to provide the child directive with access to that scope function while maintaining isolation of the parent, you can add that function as a scope: { ... } property on the parent directive:
scope: {
...
emptyCart: '='
}
and set the function name to the corresponding attribute on the parent directive's view declaration:
<div ... data-show="showPopup" empty-cart="emptyCart"></div>
Then you can skip all of the workarounds you've attempted to employ in your Plunker, and just set an ng-click on the child directive in order to fire the controller function:
sHTML = "<button ... ng-click='emptyCart()'>Empty cart</button>";
Demo