I'm trying to nested some directives on the examples looks like I got everything I need but not work as I expect, but if I put the nested directive out of the parent directive it is recognized
here is a plunker:http://plnkr.co/edit/eZaYTHm274zWx8GPMAS0?p=preview
the main purpose of this nested directives is to share the data between controllers and build a set of fields dynamically.
Thanks in advance!
Resource: https://docs.angularjs.org/guide/directive
You have two problems with your code: the restrict property and the transclude/template properties. See the code excerpt below.
return {
restrict: 'AE', //You need to add "A" if you are using attributes
transclude: true, // You need to include the ng-transclude directive in your template
template: '<div> Some Html <div ng-transclude></div></div>',
...
};
Related
I am fairly new to Angular and still learning. I posted a question regarding how to pass scope data to directives. Two nice people answered my question but the explanations were very short, so I do not understand some of the code in two of the answers. I will post the two answers and accompanying code here, and if possible someone with be able to answer my questions.
1st set of Code
<li my-directive price="item.price" ng-repeat="item in products">{{item.name}} — {{item.price}}</li>
myApp.directive('myDirective', function(){
return {
scope: { price: '=' },
require: 'ngModel',
link : function(scope){
console.log(scope.price)
},
controller: function(scope, element, attrs, ngModel){
console.log(ngModel.price);
console.log(scope.price);
}
}
});
point 1
Why is scope declared in the directive ? Regarding 'isolated scope' property name has to be price, is there a reason for the variable name here? Can we give it a different name ?
point 2
I am new to ng. This is the first time I've noticed a 'controller declared in directive'. When and why do people declare a controller in a directive? Mostly we declare a controller outside of a directive. Are a controller function and a controller inside a directive both the same, or different?
point 3
What is the meaning of require: 'ngModel', ? If we do not write require: `ngModel what will fail to work?
2nd set of Code
angular.module('myApp')
.directive('myDirective', function () {
return {
transclude: true,
restrict: 'AEC',
scope: {
name: '=',
price: '='
},
templateUrl: 'my-directive.html',
link: function (scope, element, attr) {
}
}
}
});
<li my-directive ng-repeat="item in products" price="item.price" name = "item.name"></li>
points 1
What is transclude: true ? What is the meaning of transclude = true or false? In what kind of situation do people work using transclude: true or false?
points 2
Where I have to put file my-directive.html in folder, what would be the location of the file?
Will Angular load this template file automatically?
1st set
Point 1: why scope declared in directive ? isolated scope property name has to be price ? here can we give different name ?
Ans: scope is declared in directive so that each instance of directive will have their own scope independent of each other. No it need not be price, it can be any variable name as per your choice. It's a general practice to use variable names in context of directive's usage.
Point 2:
i am new in ng. this is first time i notice controller declared in directive. why and when people declare controller in directive ? mostly we declare controller out side of directive. controller function and controller inside in directive both are same or different?
Ans: This controller is the controller of your directive and is different than what you normally see for a module.
Point 3:
what is meaning of require: 'ngModel', ? if we do not write require: `ngModel then what will not work?
Ans: When using your directive, it forces it to be used along with the attribute/controller ng-model. You can refer this answer for more details.
2nd set
Point1: what is transclude: true ? what is the meaning of transclude = true or false? in what kind of situation people work with transclude: true or false?
Ans:It's setting transclude as true. As per documentation:
Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.
transclude: true allows us to wrap a users template with our template. I've used it as true in a directive I wrote where if a table is empty, I show a error message showing No Data Available. In my case, table will not by displayed at all, instead this directive's template is displayed.
Points 2:
where i have to put the file my-directive.html in folder. what would be the location of the file?
angular will load this template file automatically?
Ans: You can place this template anywhere in the project folder. Like, in a folder named views or templates. As long as you provide correct path in templateUrl, angular will find the file and use it in the directive.
while using ui-select, I find it's too complicate to write, so I want to simplify it by creating my own directive. But it doesn't work.
.directive('crmSelect', function($rootScope) {
return {
restrict : 'E',
replace : true,
transclude : true,
scope : true,
template : '<ui-select> </ui-select>'
};
})
And the html is fairly easy:
<crm-select> </crm-select>
while running the code, angular report error (Error: [$compile:multidir] http://errors.angularjs.org/1.4.4/$compile/multidir?p0=crmSelect&p1=%20(mod…3A%20crmui.controllers)&p2=uiSelect&p3=&p4=transclusion&p5=%3Cui-select%3E)
But if I replace the template to be something like template: 'abcde ' , then it works as expected, if I directly use ui-select element in html, it also works correctly.
From the error messages, looks like there is conflict for multiple directives, does anyone knows the root cause and how to fix this?
Thanks a lot.
Following can be the reasons
Multiple directives requesting isolated scope.
Multiple directives declared with the transclusion option.
Multiple directives attempting to define a template or templateURL.
I am probably vastly simplifying the use of directives, but to me it seems like templateUrl in directives are much like partials in that you load reusable templates with <directivename></directivename> much like <%= render 'partial' %>.
Here's an example of something I just wrote before coming up with this question:
app.directive('filters', function() {
return {
restrict: 'E',
templateUrl: "../templates/product-filters-template.html"
}
});
app.directive('results', function() {
return {
restrict: 'E',
templateUrl: "../templates/product-results-template.html"
}
});
That feels identical to cutting a piece of ERB into a _partial.html.erb file.
Are directives used in any other way?
Using directives to render the same markup (same concept as a partial) is one usage, but they can also (and more frequently in my limited experience) be used to control behavior of an element. From the documentation on directives:
What are Directives?
At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children.
For example, you can use a directive to do validation of a user's input into an input element. I would strongly suggest that you read the documentation on directives.
I have the following set up as a directive in my angular project:
{
restrict: "AE",
replace: true,
template: template,
require: "ngModel",
scope: {
chosen: "=ngModel",
choices: "=choices",
placeholder: "#placeholder"
}
}
I have everything working internally for my directive, the missing piece right now is that when I select a value inside of it, the parent scope containing my directive isn't receiving any kind of update. Despite me making assigments to chosen from anywhere inside of my directive.
As the title states, what's the simplest way for me to assign a value chosen inside of my directive, to it's parent's scope?
Ideally I'd like the solution to:
Not require me to use the link function - I feel like this can be done declaratively
Not require my directive to guess anything about it's parent scope
As a followup question, is there any reason to use ngModel in this circumstance? Is it or could it be beneficial? Or could I just as easily get away with recycling a name attribute which contains the parent scope's desired return value?
I have created a plunker in order to emphasize the problem:
http://plnkr.co/edit/QHUpCv?p=preview
If I remove the custom attribute, or move the ng-select out of it, the companies are listed as the should, in case I use ng select with or within the custom attribute directive that I have created it breaks.
I suspect that some kind of $watch is required there inside of the scope for menuCtrl, but I have no idea whatsoever how to implement it.
As far as i can tell, the problem is that you are generating a new scope for your directive, so a quick fix would be to forbid that via:
// [...]
restrict: "A",
scope: false,
link: //..
I made a plunkr here to illustrate.
If you do want it this way and prefer an own scope for this directive, you can pass in the values for the select, i.e.
<div restrict companies="companies" access="admin">
and read it in in the scopeof the directive:
restrict: 'A',
prioriry: 100000,
scope: {
companies: '='
},
of course, you would then use the companies directly with the select:
<select ng-model="data.selectedCompany" ng-options="company for (id, company) in companies">