I created an angularjs directive and it is not recognized when executed.
app.directive('someDirective', function(){
return {
restrict: 'AE',
replace: 'true',
transclude: 'true',
scope: {
info: "="
},
templateUrl: '../info.html'
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
// info.html
<div>
<img ng-src="someimage.jpg"/>
</div>
<div ng-transclude></div>
//index.html
<ul>
<li ng-repeat="part in parts">
<some-directive info="part">
<div>
click here
</div>
</some-directive>
</li>
</ul>
maybe it is something with the ng-repeat?
I have a directive that looks just like it and it works..
Thank you!
answers for some of the questions:
I didn't add all of my app code.. only the parts relevant to the question.
There are other directives in the code that are written similar to this one,
they are placed in the same file as this one so the path is definitely right.
All templates are placed in the same directory this directive so again - templateUrl is right.. but for some reason this is the only directive that doesn't show. and there is no error in the console.
when putting a breakpoint in the directive return code it does not stop there.. it's like the directive is not recognized at all.
Related
I have created a ng-transclude sample which is not working when I use ng-include inside directive template property.Below are the code I have tried
angular.module("app",[]);
angular.module("app").controller('appController', function ($scope) {
$scope.message="Message from controller";
});
angular.module("app").directive('myFrame', function () {
return {
restrict: 'E',
template : '<div ng-include=\"getTemplateUrl()\"></div>',
controller:function($scope){
$scope.hidden=false;
$scope.close=function(){
$scope.hidden=true;
}
$scope.getTemplateUrl=function(){
//dynamic url
return "frame.html";
}
$scope.message="message from directive";
},
transclude:true,
}
});
angular.module("app").directive('mychildFrame', function () {
return {
restrict: 'E',
templateUrl:"childframe.html",
controller:function($scope){
},
}
});
childFrame.html
<h2>I am from Child</h2>
<div></div>
frame.html
<div class="well" style="width:350px;" ng-hide="hidden">
<div style="float:right;margin-top:-15px">
<i class="glyphicon glyphicon-remove" ng-click="close()" style="cursor:pointer"></i>
</div>
<div ng-transclude>
/*frame content goes here*/
</div>
</div>
index.html
<my-frame>
<mychild-frame></mychild-frame>
</my-frame>
https://plnkr.co/edit/O58voI?p=preview
When I change to the property template to templateUrl="frame.html" it's working fine. But the problem is, this HTML page inside the template is dynamic. So I end up with ng-include.
Could you please provide any possible workaround?
When using the templateUrl property you can also pass it a function to dynamically load a template.
There's no need to put the function in a controller, especially since it doesn't really belong there anyway: the controller is supposed to contain view logic, not a function to load the view itself.
I added the function in the templateUrl instead in your plunkr:
templateUrl : function() {
return 'frame.html';
}
https://plnkr.co/edit/HQHI9hkTojkZFK2Gjxfw?p=preview
As you can see this gives you the desired behavior
I am trying to call a controller from directive....Here is the code which i am writing
penApp.directive('enpo', function() {
return {
restrict: 'E',
scope: {
info: '=',
dragEvent: '&dragParent'
},
templateUrl: 'enpo.html',
link: function(scope, element, attrs){
var circleDiv = element.find(".circle")
element.droppable({
})
element.draggable({
handle: ".circle",
drag: function( event, ui ) {
scope.dragEvent();
}
});
var eDiv = element.find(".temp")
$(eDiv).draggable({revert: true});
}
};
})
and this is the code for .html file
<div class="row ">
<div id="n_div" class="col-xs-12 dd_area">
<end-point drag-parent="drawLine()" ng-repeat="info in stageObjectArray" info="info"></end-point>
</div>
</div>
and this is the function i have written in controller
$scope.drawLine = function(){
console.log("Called thsssssse function")
}
I am not able to figure out what is going wrong here...can anyone please guide...the controller function is not getting called
Can you please be a little clearer what each piece of code is?
Hope this will help you out:
Looks to me like you have created a directive with a link function and an html template.
From the HTML template you are trying to call the function in a controller that you have written, however I do not see that you are attaching the controller to the HTML, where you want to use it.
Try adding ng-controller="MyController" (MyController being the name of your controller which contains the $scope.drawline function) to your HTML, as follows:
<div class="row ">
<div id="n_div" class="col-xs-12 dd_area" ng-controller="MyController">
<end-point drag-parent="drawLine()" ng-repeat="info in stageObjectArray" info="info"></end-point>
</div>
</div>
BTW, I don't see where you are actually using your 'enpo' directive in your HTML. I am assuming that you are in fact calling it, but omitted that part of the code here.
I am using Bootstrap UI's accordion directive. This uses transclusion under the hood. I have some logic that needs repeated, so I am trying to create a directive that wraps the accordian, which also uses transclusion.
<div>
<div accordion>
<div accordion-group is-open="isOpen">
<div accordion-heading>
<span class="glyphicon" ng-class="{'glyphicon-minus-sign': isOpen, 'glyphicon-plus-sign': !isOpen}"></span>
<strong>{{headerTitle}}</strong>
</div>
<div ng-transclude></div>
</div>
</div>
</div>
Here is the JavaScript:
application.directive('collapsePanel', ['baseUrl', function (baseUrl) {
return {
restrict: 'A',
templateUrl: baseUrl + 'content/templates/collapse_panel.html',
replace: true,
transclude: true,
scope: {
headerTitle: '#'
},
controller: ['$scope', function ($scope) {
$scope.isOpen = false;
}]
};
}]);
It should be as simple to use as:
<div collapse-panel header-title="Title">
{{scopeVariable}}
</div>
Assuming scopeVariable is in my controller, I would think its value would appear. From what I can tell, the scope belongs to the collapse-panel rather than the outer scope. It is almost like having nested transclusion directives is causing my problem.
Is there a trick to nesting transclusions like this?
To start, I set up a JSFiddle here: http://jsfiddle.net/qLagkgt5/3/
I hope the title is clear, but basically, I am trying to use directives to help in repeatable html. In the example on JSFiddle, I am using a box directive with options for spacing and box-type.
The html that I am turning into repeatable code:
<div class="box">
<div class="box-inner">
{{CONTENT GOES HERE}}
</div>
</div>
With optional classes:
<div class="box spacing-small box-rounded">
<div class="box-inner">
{{CONTENT GOES HERE}}
</div>
</div>
What I'd like to be able to do is:
<box spacing="small" box-type="rounded">
{{CONTENT GOES HERE}}
</box>
This is obviously a very simplified set of html that doesn't necessarily need a directive, but it is just an example to illustrate what I am running into.
Now to the angular side of things...
Here is my controller:
app.controller("Ctrl", ["$scope", function($scope) {
$scope.text = "Starting Text... FOOBAR!";
}]);
And here is my directive:
app.directive("box", function() {
return {
restrict: "E",
transclude: true,
replace: true,
scope: {
spacing: "#",
boxType: "#"
},
template: '<div class="box" ng-class="{\'spacing-{{spacing}}\' : spacing, \'box-{{boxType}}\' : boxType}"> <div class="box-inner" ng-transclude></div></div>'
}
});
If I now place my directive inside html with a controller like this:
<div class="wrap" ng-controller="controller">
{{text}}
<box spacing="small">
<input ng-model="text"/>
</box>
</div>
The $scope.text that is outside the <box> is never updated when I change the input inside the box.
How do I make it so that when this directive is used, the content inside the box goes up to the parent scope rather then the isolated scope?
If I nest a box inside another box, can I also have it go up to the same parent scope?
Thanks!
I read something here on stackoverflow that immediately jumped in my head when I read your post. It said something like "If you do it without a dot you are doing it wrong..." I'll search for the article and post it here as soon as I found it but for now I think I "fixed" your code:
<div ng-app="app" ng-controller="Ctrl">
<h1><span class="grey">$scope.data.text:</span> {{data.text}}</h1>
<box spacing="large" box-type="rounded">
<h2><span class="grey">$scope.text in box directive:</span> {{data.text}}</h2>
<input ng-model="data.text" />
</box>
<box spacing="small" box-type="rounded-shadow">
<h2><span class="grey">$scope.text in different box directive:</span> {{data.text}}</h2>
<input ng-model="data.text" />
</box>
</div>
var app = angular.module("app", []);
app.controller("Ctrl", ["$scope", function($scope) {
$scope.data = {};
$scope.data.text = "Starting Text... FOOBAR!";
}]);
app.directive("box", function() {
return {
restrict: "E",
transclude: true,
replace: true,
scope: {
spacing: "#",
boxType: "#"
},
template: '<div class="box" ng-class="{\'spacing-{{spacing}}\' : spacing, \'box-{{boxType}}\' : boxType}"> <div class="box-inner" ng-transclude></div></div>'
}
});
You have to create an object and use this for databinding. I am now using "data.text" and do the binding with this expression.
Cheers,
Tim.
P.S.: There are a lot of links.
To mention only two:
AngularJS: If you are not using a .(dot) in your models you are doing it wrong?
AngularJS: dot in ng-model
I am trying to create a template that shows some transcluded content. When I use ng-show everything works fine, but using ng-if or ng-switch gives me problems. I get this error message: Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found
I understand that ng-switch creates a new scope. But the transclude should still go up to the parent chain. Is this a defect in angularjs? See http://jsfiddle.net/HgvP7/
Here is my html, modified from the documentation example:
<div ng-app="docsTransclusionExample">
<div ng-controller="Ctrl">
<my-dialog>Check out the contents, {{name}}!</my-dialog>
</div>
<!-- my-dialog.html -->
<script type="text/ng-template" id="my-dialog.html">
<div ng-switch="1+1">
<div ng-switch-when="2">
<div ng-transclude></div>
</div>
</div>
</script>
</div>
And the code:
angular.module('docsTransclusionExample', [])
.controller('Ctrl', function($scope) {
$scope.name = 'Tobias';
})
.directive('myDialog', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
templateUrl: 'my-dialog.html',
link: function (scope, element) {
scope.name = 'Jeff';
}
};
});