Directive is Not Called when the ng-repeat is finished - angularjs

I want to call the directive when my ng-repeat is finished. I use two controllers with same name. My problem is that when I call the function of controller the function changes the value of the list. And base on that list ng-repeat is work. When ng-repeat is end directive is called that called the END function. But ng-repeat not work as well as directive also not called.
my HTML code is here
> <body ng-app="modules" >
<div class="container" >
<div class="row" ng-controller="mainctl">
<div class="col-sm-1">
<a href="#" ng-click="divide(1)" ><h3>1*1</h3></a>
</div>
<div class="col-sm-1">
<h3>2*2</h3>
</div>
<div class="col-sm-1">
<h3>3*3</h3>
</div>
<div class="col-sm-1">
<h3>4*4</h3>
</div>
<div/>
<div ng-controller="mainctl">
<div ng-repeat="rows in cells" > <!-- repeat fot rows -->
<div class="row">
<div ng-repeat="cols in cells" repeat-end="onEnd()"> <!-- repeat for colums -->
<div id="Div_{{rows}}{{cols}}" class="col-sm-2 rcorners2">
<center><h1>{{rows}}{{cols}}</h1></center>
<div id="divPictureBoxPlayback{{rows}}{{cols}}" class="pictureboxPlayback'"
ad-drop="true"
ad-drop-end="onDrop($data, $dragElement, $dropElement, $event);" >
<div id="divHeaderPictureBoxPlayback{{rows}}{{cols}}" class="panel panel-default margin-b-0 text-center pictureboxHeader row"
ng-hide="StartPlayerPlayback{{rows}}{{cols}}" >
<div class="">
<span class="col-lg-3 col-xs-3 col-md-3 text-left">{{cameraNamePlayback00}}</span>
<span class="col-lg-9 col-xs-9 col-md-9 text-right pad-0">
<button class="margin-r-10 btn btn-xs" ng-click="StopStreaming('{{rows}}{{cols}}')"><i class="fa fa-close"></i></button>
</span>
</div>
</div>
<div id="divStreamingAreaPlayback{{rows}}{{cols}}" class="video-cointainer text-center row" ng-hide="StartPlayerPlayback{{rows}}{{cols}}"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
here is my controller
app.controller('mainctl', function ($scope,$timeout) {
$scope.cells =["0"];
//Scopes.store('mainctl', $scope);
$scope.divide = function (ar)
{
$scope.value = ar;
$scope.cells = [];
for (var i = 0; i < ar; i++)
{
$scope.cells.push(i + "");
}
}
$scope.divide1=function()
{
for(var i=0;i<$scope.value;i++)
{
for(var j=0;j<$scope.value ;j++)
{
$scope.index=""+i+j;
$("#divPictureBoxPlayback" + $scope.index).attr('class', 'picturebox pictureboxPlayback' + i + j);
$("#divPictureBoxPlayback" + index).show();
}
}
}
$scope.onEnd = function(){
$timeout(function(){
alert('all done');
$scope.divide1();
}, 1);
}
});
here is my directive
app.directive("repeatEnd", function($timeout){
return {
restrict: "A",
link: function (scope, element, attrs) {
if (scope.$last) {
alert("last element ");
scope.$eval(attrs.repeatEnd);
}
}
};
})

It seems you are missing timeout. You will need timeout in your code in directive:
app.directive("repeatEnd", function ($timeout) {
return {
restrict: "A",
link: function (scope, element, attrs) {
if (scope.$last) {
$timeout(function () {
alert("last element ");
scope.$eval(attrs.repeatEnd);
});
}
}
};
})
$timeout will ensure it is executed only when ng-repeat finishes its rendering. The reason for using $timeout over setTimeout is because it will call $apply internally.

Related

Delete json object from directive

hello I want to delete json in angularjs
for the first time I only use ng-repeat directive
<div ng-repeat="artworkItem in artworksItems | filter: {category:'artworks'}| filter:query" class="">
<p>{{artworkItem.name}}</p>
<button ng-click="remove($index)">delete</button>
</div>
controller
ItemFactory.get().then(function(data) {
$scope.artworksItems = data;
});
$scope.remove= function(index){
$scope.artworksItems.splice(index, 1);
}
it works. Then i try to move it with directive.
so my code will be like this
<div ng-repeat="artworkItem in artworksItems | filter: {category:'artworks'}| filter:query" class="">
<grid-artworks data="artworkItem"></grid-artworks>
</div>
directive.html
<div>
<div class=" col-xs-6 col-sm-4 col-md-3 productThumbnail">
<a href="#/Artworks/{{data.id}}" class="">
<img ng-src="{{data.imgUrl}}" alt="{{data.name}}" class="img-responsive">
</a>
<div class="caption">
<p class="title text-center">{{data.name}}</p>
<p class="text-center">{{data.priceTotal}} {{data.curency}}</p>
<button ng-click="remove($index)">d</button>
</div>
</div>
</div>
directive.js
angular
.module('app.directives.gridViewArtworks',[])
.directive('gridArtworks',function()
{
return{
restrict:'E',
scope:{
data: '='
},
transclude:true,
replace:true,
templateUrl:"templates/directives/gridViewArtworks.html",
controller:function($scope){
console.log($scope.data);
}
};
}
);
controller
ItemFactory.get().then(function(data) {
$scope.artworksItems = data;
});
$scope.remove= function(index){
$scope.artworksItems.splice(index, 1);
}
with directive I can't delete the item. Please help me why can't I delete the data.
Pass a callback to your directive from the controller, which will be triggered from removing the element from the array.
scope:{
data: '=',
onRemove: '&'
},
Then when you call the directive:
<grid-artworks data="artworkItem" on-remove="remove(id)"></grid-artworks>
And inside your directive:
<button ng-click="onRemove({id: data.id})">d</button>
And change your remove function in the controller in order to use the id for removing elements from the array, because it's safer than the $index:
$scope.remove= function(id){
$scope.artworksItems.splice($scope.artworksItems.findIndex(el => el.id === id), 1);
}
You could pass index as an attribute.
<grid-artworks data="artworkItem" index="{{$index}}"></grid-artworks>
You'll need to add it to your directive's scope.
scope: {
index: '#',
// ...
And then you can use it.
<button ng-click="remove(index)">d</button>
Alternatively, you should be able to do remove(data):
var index = $scope.artworksItems.indexOf(data);
$scope.artworksItems.splice(index, 1);

Adding html to UI bootsrap popover inside directive

I am an angular beginner and I wish to add an html button inside a popover that I am creating within a directive. Specifically, my directive allows the user to highlight text on the page and a popover will then appear around the selected text. It works for plain text content in the popover but not html. This is the directive as it is now
app.directive('replybox', function ($timeout, $window, $compile, $sce) {
var linkFn = function (scope, element, attrs) {
var exampleText= element.find('p');
var btn = element.find('button');
var windowSelection="";
exampleText.bind("mouseup", function () {
scope.sel = window.getSelection().toString();
windowSelection=window.getSelection().getRangeAt(0);
if(scope.sel.length>0) {
scope.showModal = true;
scope.$apply();
}
});
btn.bind("click", function () {
range = windowSelection;
var replaceText = range.toString();
range.deleteContents();
var div = document.createElement("div");
scope.pophtml = $sce.trustAsHtml("<p>hello world</p> <button>x</button>");
div.innerHTML = '<poper>' + replaceText + '</poper>';
var frag = document.createDocumentFragment(), child;
while ((child = div.firstChild)) {
frag.appendChild(child);
}
$compile(frag)(scope);
range.insertNode(frag);
scope.selection="None";
});
};
return {
link: linkFn,
restrict: 'A',
scope: {
entities: '=',
selection:'='
},
template: `<ng-transclude></ng-transclude>
<div class="modal fade in" style="display: block;" role="dialog" ng-show="showModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
{{sel}}
</div>
<div class="radio">
<div ng-repeat="x in entities">
<div class="radio">
<label>
<input type="radio" name="choice" ng-model="$parent.selection" ng-value = "x">
{{x}}
</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" ng-click="showModal=false">
Ok
</button>
</div>
</div>
</div>
</div>`,
transclude: true
};
});
The part that is not working is this part
scope.pophtml = $sce.trustAsHtml("<p>hello world</p> <button>x</button>");
div.innerHTML = '<poper>' + replaceText + '</poper>';
I have a feeling there is something wrong with the above two lines.

`ng-click` not calling the controller function some times

I have 2 popup's which is controller by a service in a page. on click on the div element i am calling the controller function. after i added the 2nd popup directive especially some times the ng-click not working properly. how to solve this?
here is my service.js
"use strict";
angular.module("tcpApp").service("modalService", function ( $rootScope) {
//header configuration
$rootScope.hideModal = function() {
$rootScope.showModal = false;
};
this.changePass = function ( configId ) {
$rootScope.showModal = true; //this is for global
$rootScope.currentConfigPopView = 'views/tools/'+configId+'.html';
$rootScope.$apply();
};
this.showSummary = function () {
this.showSummaryPop = true;
}
this.hideSummary = function () {
this.showSummaryPop = false; //this is within controller
}
});
html:
<div class="statusBoard board8" ng-click='modal.showSummary("board8")'>
<span><img src="../images/iconDetails.png" alt="icon plan and actual"></span>
<h2>{{boardAssets.board8.title}}</h2>
<span class="row dwo">
<span class="catg">Total Issue Reported</span>
<span class="cd issueData">{{contractor.IssueDetails.TotalIssue}}</span>
</span>
<span class="row mas">
<span class="catg">Issue Resolved</span>
<span class="cd resolveData">{{contractor.IssueDetails.IssueResolved}}</span>
</span>
<span class="row rfi">
<span class="catg">Issue Remaining</span>
<span class="cd remainData">{{contractor.IssueDetails.IssueRemaining}}</span>
</span>
</div>
<body-footer></body-footer>
<config-popup></config-popup> //after i added this directive getting ng-click issue.
<modal-popup></modal-popup>
config popup html:
<div class='ng-modal' ng-if="showModal">
<div class='ng-modal-overlay' ng-click='hideModal()'></div>
<div class='ng-modal-dialog' ng-style='dialogStyle'>
<div class='ng-modal-dialog-content'>
<ng-include src="currentConfigPopView"></ng-include>
</div>
</div>
</div>

angular does not load my directive

I newly start to use angular.but I have some problem to loading my directive.
I want to load my directive as soon as page loaded.
where I load data-show directive
<div class="row">
<div class="col-md-12">
<article class="row" ng-controller="DataCtrl">
<input type="button" ng-click="getDataList()" >
<h1>Some Content Here</h1>
<ul id="home" bread-crumbs></ul>
<ul class="thumbnails">
<li ng-repeat="data in list" class="col-md-5">
<show-data data="data"/>
</li>
</ul>
</article>
</div>
</div>
showData directive:
app.directive('showData', function () {
return{
restrict: 'E',
replace:true,
templateUrl: 'views/directives/datas.directive.html',
scope: {
data: "="
},
controller:'DataCtrl'
}
})
and template I used in:
<div class="well hoverwell">
<div class="row">
<h2 class="col-md-4">{{data.name}}</h2>
</div>
<div class="row">
<span class="col-md-1">Code:</span>
<span class="col-md-1">{{data.id}}</span>
</div>
<div class="row">
<span class="col-md-1">accountability:</span>
<span class="col-md-1">{{data.parent}}</span>
</div>
<div class="row">
<span class="col-md-1"> :</span>
<span class="col-md-1">{{data.definition}}</span>
</div>
</div>
and my controller
'use strict';
angular.module('app')
.controller('DataCtrl', function ($scope, DataService, $log) {
$scope.getDataList = function () {
var list = DataService.getDataList(1);
list.then(
function (result) {
$log.info(result);
$scope.dataList = result;
}, function (status) {
$log.error(status)
$scope.msg = "error " + status + " has been occur,please report to admin ";
});
};
});
and when I run my app it does not work .
when I watch it in chorome development tools my directive is comment
what is my problem.How can I call this directive as soon as page load.
thx
As you already noticed, you see empty list because your dataList in ng-repeat is not filled yet.
But you have some errors in your code:
First of all - you should never use one controller twice. So you need to create separate controller for your directive.
replace directive parameter is deprecated, better not to use it.
In your DataCtrl you set the dataList variable: $scope.dataList = result;, but in HTML you refer to list variable: <li ng-repeat="data in list" class="col-md-5">.
Maybe that example will help you to figure out with your code.

how to handle scope in angular js

I am working with angular js for my dashboard. I have an over all minimize button to minimize all widget and then each widget have own minimize button. I done with following script its not working.
when i click widget minimize button its minimize all widget. but i want minimize that widget only.
var dashboard = angular.module("dashboard",['ui.bootstrap']);
dashboard.controller('dash-control', ['$scope', function($scope) {
$scope.isHidden = false;
$scope.toggle = function(){
$scope.isHidden = !$scope.isHidden;
};
$scope.toggleonce= function()
{
if( this.isHidden === true)
this.isHidden = false;
else
this.isHidden = true;
};
}]);
HTML code like follow:
<div class="contentpanel" ng-app="dashboard" ng-controller="dash-control as ctrl">
<button class="btn btn-white" type="button" ng-click="toggle()"><i class="fa fa-minus-square"> </i> </button>
<div>
<i class="fa fa-minus"></i>
<div class="row tinychart" ng-show="isHidden">Contenr Heading 1</div>
<div class="row tinychart" ng-hide="isHidden">Content Description 1</div>
</div>
<div>
<i class="fa fa-minus"></i>
<div class="row tinychart" ng-show="isHidden">Contenr Heading 2</div>
<div class="row tinychart" ng-hide="isHidden">Content Description 1</div>
</div>
......
.....
.....
</div>
I would rather create a directive with isolated scope for represent a inner widget. for instance;
dashboard.directive('myWidget',function(){
return {
scope:{},
template:"<div>\r\n<a href=\"\" class=\"tooltips\" ng-click=\"toggleonce()\" title=\"Minimize Panel\"><i class=\"fa fa-minus\"><\/i><\/a>\r\n<div class=\"row tinychart\" ng-show=\"isHidden\">asdasdasd<\/div>\r\n<div class=\"row tinychart\" ng-hide=\"isHidden\">sdasdasd<\/div>\r\n\r\n <\/div>",
link:function($scope)
{
$scope.isHidden = false;
$scope.toggle = function(){
$scope.isHidden = !$scope.isHidden;
};
$scope.togglesingle = function()
{
if( this.isHidden === true)
this.isHidden = false;
else
this.isHidden = true;
};
}
}
});
Then In Html Body;
<div class="contentpanel" ng-app="dashboard" >
<button class="btn btn-white" type="button" ng-click="toggle()"><i class="fa fa-minus-square"> </i> </button>
<div my-widget></div>
<div my-widget></div>
</div>
Note that I haven't run and check the example. I hope you got the idea.
Edited:
The ng-repeat will loop the array (list) and initiate each element to 'item' variable. You can pass that data to your directive. Check the updated code.

Resources