angularjs directive calls image effect script - angularjs

I have a directive to make news item to have an effect like usatoday.com when user hover on the news. I'm new to angularjs :D
Directive:
app.directive('hotEvent', ['$rootScope', function ($rootScope) {
return {
restrict: 'EA',
templateUrl: '/App/Main/views/home/events.html',
link: function (scope, iElement, attrs) {
//attrs references any attributes on the directive element in html
var dathumb = $(iElement).find('.da-thumbs > li a');
//$(function () {
dathumb.each(function () {
$(this).hoverdir();
});
//});
}
};
}]);
View: /App/Main/views/home/events.html
<ul class="row da-thumbs">
<li ng-repeat="news in featuredEvents">
<a href="/">
<img src="abc.jpg" /> >> no effect ???
<div>
<h4>aaa</h4>
<p>
bbb
</p>
</div>
</a>
</li>
<li>
<a href="/">
<img src="abc.jpg" /> >> show effect
<div>
<h4>bbb</h4>
<p>
ccc
</p>
</div>
</a>
</li>
</ul>
On Home.html: (which already binded with controller)
<div hot-event></div>
It works when i don't bind data from the controller <li ng-repeat="news in featuredEvents">, now the effect just doesn't show up. Console.log show 0 error.
UPDATED: i ended up using document ready
app.directive('hotEvent', function () {
return {
restrict: 'EA',
templateUrl: '/App/Main/views/home/events.html',
link: function ($scope, iElement, attrs) {
angular.element(document).ready(function () {
var dathumb = $(iElement).find('.da-thumbs > li a');
dathumb.each(function () {
$(this).hoverdir();
});
});
}
}
});

If you debug your code you'd see that your directive didn't find any elements.
It happens because when the template loads, the directive link function gets called, but the ng repeat didn't have time to populate it self (it starts off empty), there for it's no where to be found.
An easy workaround is to use the jquery find method in a setTimeout 0 function, or use $scope.evalAsync on the function that does the jquery find (it requires angular 1.3).
But the best solution would be to fix the code to actually not require jquery.
P.s. when you see your self using selectors in a directive you are usually doing things wrong in angular (note: usually), please refer to this "Thinking in AngularJS" if I have a jQuery background? awesome question and answer.
note that he actually says that when you first learn angular, don't use jquery at all :)

Related

Pass controller complex data to directive after render

just started learning angular, and having some trouble passing complex data from controller to directive that is executed afterRender. I have seen countless other posts but none seem to be my exact situations.
On HTML side:
<ul after-render="AssignSubCatExpnasion" class="inner">
<li class="titleLevelSecond" ng-repeat="SubCat1 in Categories[0].Children">
<div class="titleLevelSecondDiv toggle">
<span class="title"> {{ SubCat1.Name }} </span><span class="numbers">{{ SubCat1.Count }}</span>
</div>
<ul class="inner">
<li class="titleLevelThird" ng-repeat="SubCat2 in SubCat1.Children">
<div class="titleLevelThirdDiv">
<span class="title">{{ SubCat2.Name }}</span> <span class="numbers">{{ SubCat2.Count }}</span>
</div>
</li>
</ul>
</li>
On Angular Side:
<script>
var appGetBetCategories = angular.module('BetCategories', []);
appGetBetCategories.controller('GetBetCategories', function ($scope, $http) {
$http.get("http://localhost:49780/api/betcategory").then(function (response) {
$scope.Categories = response.data;
});
});
appGetBetCategories.directive('afterRender', ['$timeout', function ($timeout) {
var def = {
restrict: 'EA',
terminal: true,
transclude: false,
scope: {
Categories: '=',
},
link: function (scope, element, attrs) {
$timeout(scope.$eval(attrs.afterRender), 0);
}
};
return def;
}]);
Without a directive, all expressions execute properly, but I need to run js function called 'AssignSubCatExpnasion' after I am done with API call and have rendered my controls. I know I need to pass my controller scope to directive somehow, just can't wrap my head on how, since I already calling a function inside after-render="".
Any help or suggestions is greatly appreciated.

How to pass Html partial to the Custom directive's attribute in AngularJS

I am new to AngularJS and part of learning i am stuck here.
I have a custom directive on element level and it has a isolated scope attribute called Route which is assigned to a string and i am broadcasting it to another directive's controller like when ever i click on element it is navigating to another directive's template area and displaying the route message so which is working good so far and now i want to replace that string with a HTML Partial.
Any help would be appreciated, Thanks in advance.
//Directive
"use strict";
angular.module('adminMenuModule').directive('adminMenuItem',function(){
return{
require: '^adminMenu',
scope:{
label:'#',
route :'#'
},
templateUrl: 'adminMenu/adminMenuItemTemplate.html',
link: function(scope, el , attr,ctrl){
scope.isActive = function(){
return el === ctrl.getActiveElement();
};
el.on('click', function(evt){
evt.stopPropagation();
evt.preventDefault();
scope.$apply(function(){
ctrl.setActiveElement(el);
ctrl.setRoute(scope.route);
});
});
}
};
});
<!--Main admin Page-->
<admin-menu-item label="Employee Management" route="employee"></admin-menu-item>
<!-- Directive's template-->
<li class="admin-selectable-item ">
<div class="admin-noselect">{{label}}</div> <i
class="fa fa-2x fa-caret-left admin-menu-active-indicator"
ng-if="isActive()"></i>
</li>

Calling controller from directive

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.

create dynamic template in angularjs

Hi I want to create angular template dynamically like below:
Index.html:
<div ui-view></div>
<ul class="nav-links">
<li ng-repeat="item in items">
<a ui-sref="{{item.id}}"">{{item.name}}</a>
</li>
</ul>
<script ng-repeat="item in items" type="text/ng-template" id="{{item.id}}.html">
<h1>{{item.name}}</h1>
</script>
How could I do that? I searched on web and found that we can include template dynamically, but I did not find any place where it is specified that how to create template itself dynamically.
Thanks,
Sombir
The best way you can do that is Custom Directives! it is what makes angularjs powerfull.
.directive('myCustomer', function() {
return {
restrict: 'E',
template: 'myCustomer.html'
};
});
and in your index or whatever you can call it:
<my-customer></my-customer>
EDIT:
To generate dynamicaly your Custom directive Use the property Controller or Link.
.directive('myCustomer', function() {
return {
restrict: 'E',
template: 'myCustomer.html',
controller: function ($scope,$http) {
// here you can use $scope, $http etcs... but
}, // to make it clean and standard use Link
link: function (scope, element, attrs) {
// do all stuff like API call JQuery stuff and all here
}
};
});
with that you can generate dynamicaly you directive :) from an API or whatever you want to. :)

AngularJS directive for accessing ng-repeat scope of child

Okay, so let me start off saying that I have a directive that creates a JQueryUI tab setup with a backing field that populate the tab name and the tab contents basically.
<div id="summaryTabPanel">
<ul>
<li ng-repeat="category in SummaryCategories">
{{category.Name}}
</li>
</ul>
<div ng-repeat="category in SummaryCategories" id="tabs-{{$index + 1}}">
{{category.Content}}
</div>
</div>
So as you can see, I have a <ul> with an ng-repeat in the <li>.
As I will be applying JQueryUI Tab function to the parent container id="summaryTabPanel", I need to wait until all the dom is rendered.
So I do some research, and find out I need to create a directive that kind of looks like the following:
Application.Directives.directive("repeatDone", function () {
return {
restrict: "A",
link: function (scope, element, attrs) {
scope.$watch("repeatDone", function () {
if (scope.$last) {
$("#summaryTabPanel").tabs({
event: "mouseover"
});
}
;
});
}
};
});
This watches to see if the last repeated item is found, and then applies the DOM changes via the statement $("#summaryTabPanel").tabs()
This is all fine and good, but it only works if I apply the directive to the last ng-repeated child item of the summaryTabPanel container.
<div id="summaryTabPanel">
<ul>
<li ng-repeat="category in SummaryCategories">
{{category.Name}}
</li>
</ul>
<div ng-repeat="category in SummaryCategories" id="tabs-{{$index + 1}}" repeat-done>
{{category.Content}}
</div>
</div>
If I move it to the previous ng-repeat item things work but not quite right. If I move it to the parent container, things don't work at all.
It seems wrong to me to apply this directive to the last child, and instead have a way to apply it to the root and somehow accomplish the same thing.
<div id="summaryTabPanel" repeat-done>
Is this possible somehow with Angular?
According to this link you should write your directive like this
Application.Directives.directive("repeatDone", function () {
return {
restrict: "A",
link: function (scope, element, attrs) {
$timeout( function () {
$("#summaryTabPanel").tabs({
event: "mouseover"
});
});
}
});
Please have a look at the jsfiddle I created to illustrate your case.

Resources