AngularJS Directive failing apply because $apply is already running - angularjs

Error: [$rootScope:inprog] http://errors.angularjs.org/1.2.7/$rootScope/inprog?p0=%apply
Hi! I'm making a mini calendar standalone directive and I'm having trouble applying the changes of the months and the day. It tells me $apply is already in progress, I have google around and notice it's a problem when using it inside a compile definition object.
But preventing the $apply from running when it's already doing it didn't solve things, since it seems like its always running. Any suggestion or fixes for my issue would be appreciated :D
Controller + Directive
function calendarController($scope) {
$scope.config = new Date(2013, 4, 25);
}
angular.module("calendar", []).directive('miniCalendar', function($parse) {
return {
restrict: "E",
replace: true,
templateUrl: "../views/template.html",
transclude: true,
controller: function($scope) {
$scope.currentDate = new Date();
$scope.prev = function() {
$scope.mCalDate = new Date($scope.mCalDate.getFullYear(), $scope.mCalDate.getMonth() - 1, $scope.mCalDate.getDay());
$scope.updateDate($scope.mCalDate);
};
$scope.next = function() {
$scope.mCalDate = new Date($scope.mCalDate.getFullYear(), $scope.mCalDate.getMonth() + 1, $scope.mCalDate.getDay());
$scope.updateDate($scope.mCalDate);
};
$scope.selecting = false;
$scope.selectDate = function() {
$scope.selecting = !$scope.selecting;
};
$scope.selectDay = function(day) {
$scope.mCalDate = day.date;
$scope.updateDate($scope.mCalDate);
};
$scope.currentMonth = '';
$scope.currentYear = '';
$scope.days = [{
day: "Sun"
}, {
day: "Mon"
}, {
day: "Tue"
}, {
day: "Wed"
}, {
day: "Thu"
}, {
day: "Fri"
}, {
day: "Sat"
}];
$scope.weeks = [];
},
scope: {
mCalDate: '='
},
compile: function(element, attrs) {
var modelAccessor = $parse(attrs.mCalDate);
return function(scope, element, attrs, controller) {
scope.currentDate = scope.mCalDate.getDate() + '/' + Math.abs(scope.mCalDate.getMonth() + 1) + '/' + scope.mCalDate.getFullYear();
var firstDayOfMonth = new Date(scope.mCalDate.getFullYear(), scope.mCalDate.getMonth(), 1).toDateString().split(' ');
var totalDays = new Date(scope.mCalDate.getFullYear(), scope.mCalDate.getMonth() + 1, 0).getDate();
var firstDayIndex;
for (var i in scope.days) {
if (scope.days[i].day == firstDayOfMonth[0]) {
firstDayIndex = i;
}
}
var allDays = [];
var h = 0;
for (i = 0; i < totalDays + 6; i++) {
if (i >= firstDayIndex && (h + 1) <= totalDays) {
allDays.push({
dayName: scope.days[new Date(scope.mCalDate.getFullYear(), scope.mCalDate.getMonth(), h + 1).getDay()].day,
day: ++h,
date: new Date(scope.mCalDate.getFullYear(), scope.mCalDate.getMonth(), h + 1)
});
} else {
allDays.push({});
}
}
var calendar = []
var chunk = 7;
for (i = 0, allDays.length; i < allDays.length; i += chunk) {
calendar.push({
week: calendar.length,
days: allDays.slice(i, i + chunk)
});
}
scope.weeks = calendar;
scope.currentYear = scope.mCalDate.getFullYear();
scope.currentMonth = scope.mCalDate.toDateString().split(' ')[1];
scope.$watch('mCalDate', function(val) {
//debugger;
});
scope.updateDate = function(date) {
scope.mCalDate = date;
var phase = scope.$root.$$phase; //Safe applying
if (phase != '$apply' || phase != '$digest') {
scope.$apply(function() {
scope.mCalDate = date;
$parse(attrs.mCalDate).assign(scope.$parent, 'config');
});
}
};
};
}
};
});
HTML
<mini-calendar type="text" m-cal-date="config" />
Template
<div class="miniCalendar"><label ng-click="selectDate()"><input type="text" ng-model="currentDate" disabled></label><div ng-show="selecting"><div><a><span ng-click="prev()">Prev</span></a><a><span ng-click="next()">Next</span></a><div ><span ng-bind="currentMonth">January</span> <span ng-bind="currentYear"></span></div></div><table><thead><tr><th ng-repeat="day in days"><span ng-bind="day.day"></span></th></tr></thead><tbody><tr ng-repeat="week in weeks"><td ng-repeat="d in week.days"><a ng-bind="d.day" ng-click="selectDay(d)">1</a></td></tr></tbody></table></div></div>

Using $timeout instead of $apply can solve $digest issue.
scope.updateDate = function(date) {
$timeout(function() {
scope.mCalDate = date;
$parse(attrs.mCalDate).assign(scope.$parent, 'config');
});
};

Related

Add focus/blur event in directive not working with templateUrl

I'm on a mysterious bug since last friday and perhaps you have an explanation.
I have a directive define like that :
//------------------------------------------------------------------------------
// fl-main-menu
// Type: Element
// Description: Creates a...
//------------------------------------------------------------------------------
uiModule.directive('flNavMenu', ['$rootScope', function ($rootScope) {
//-------------------------
// CONTROLLER
//-------------------------
var componentController = function ($scope, $element, $state, localize, $stateParams, StateManager)
{
$scope.isMenuOpened = false;
$scope.buttonsData = [
{
name: "Games",
data: {
type: "navMenuIconButton",
label: "menu_Games",
imgUrl: "./images/ic-controller-w.svg",
imgUrlOver: "./images/ic-controller-w.svg",
cb: function () { StateManager.display("gameCategories"); }
}
},
{
name: "News",
data: {
type: "navMenuIconButton",
label: "News",
imgUrl: "./images/ic-news-w.svg",
imgUrlOver: "./images/ic-news-w.svg",
cb: function () { StateManager.display("newsList", { spaceId: '', newsIndex: 0}); }
}
}
];
var updateNavButtons = function (){
$scope.navButtons = [{
imgUrl: "./images/ic-menu-w.svg",
label: "Menu_Close"
}
];
if(app.fromGame){
$scope.navButtons.push({
imgUrl: "./images/navBar-ico-Y-w.svg",
label: "Btn_BackToGame"
}
);
}
};
updateNavButtons();
$scope.unregisterStageChange = $rootScope.$on('$stateChangeSuccess', function (event) {
var buttons: any = document.getElementsByClassName('fl-component navmenu-item-button');
var element : any;
if ($state.includes("newsList")) {
if (!$stateParams.spaceId)
element = buttons[2];
else
element = buttons[1];
}
else if ($state.includes("main")) {
element = buttons[0];
}
else {
element = buttons[1];
}
if (element) {
$element[0].children[0]._lastFocusElement = element;
$element[0].children[0]._focusables = buttons;
}
});
var fromGame = false;
$scope.app = app;
$scope.unwatchFromGame = $scope.$watch("app.fromGame", function (newValue, oldValue) {
if (newValue === fromGame) {
return;
}
updateNavButtons();
});
function openCloseMenu()
{
if ($element[0].style.display != 'none')
{
if ($rootScope.isVideoPlayerOpen)
{
$rootScope.$emit("closeVideo");
}
if (!$scope.isMenuOpened)
{
$scope.onViewOver();
}
else
{
$scope.onViewOut();
}
}
};
function isMenuButtonPressed(keyPressed)
{
var keyMapping = platform.getKeyMapping();
if ((platform.isPC() && keyPressed == keyMapping.Space)
|| (platform.isMobile()
&& keyPressed == keyMapping.Enter))
{
return true;
}
return false;
};
function onKeyUp(event)
{
if (isMenuButtonPressed(event.keyCode))
{
openCloseMenu();
}
};
EventManager.addEventListener(window.document.body, BaseEventType.KEYUP, BaseEventPhase.CAPTURE_PHASE, onKeyUp, this);
$scope.$on('$destroy', () => {
$scope.unwatchFromGame();
$scope.unregisterStageChange();
$element[0].children[0].onKeyDownEvent = undefined;
EventManager.removeEventListener(window.document.body, BaseEventType.KEYUP, BaseEventPhase.CAPTURE_PHASE, onKeyUp, this);
TweenMax.killTweensOf($element[0].children[0]);
TweenMax.killTweensOf($element[0].children[1]);
})
};
//-------------------------
// LINK
//-------------------------
var componentLink = function (scope, element)
{
var offset = 185;
var menu = element[0].children[0];
var tongue = element[0].children[1];
var wrapper = document.getElementById('wrapper');
/**
* Close the tongue and open the menu
*/
scope.onViewOver = function () {
var width = menu.scrollWidth;
TweenMax.killTweensOf(menu);
TweenMax.killTweensOf(tongue);
//Make the tongue disapear, and the menu appear
TweenMax.to(tongue, 0.2, { alpha: 0, ease: Quad.easeOut });
TweenMax.to(menu, 0.2, { alpha: 1, ease: Quad.easeIn });
//Open menu animation (css transition)
offset = $rootScope.app.isSnapMode ? 250 : 95;
if (wrapper) wrapper.style.left = ((width / 2) + offset) + 'px';
menu.style.left = '0px';
scope.isMenuOpened = true;
};
/**
* Close the menu and open the tongue
*/
scope.onViewOut = function () {
TweenMax.killTweensOf(menu);
TweenMax.killTweensOf(tongue);
//Make the menu disapear, and the tongue appear
TweenMax.to(tongue, 0.2, { alpha: 1.0, ease: Quad.easeIn });
TweenMax.to(menu, 0.1, { alpha: 0, ease: Expo.easeIn, delay:0.2});
//Close menu animation (css transition)
if (wrapper) wrapper.style.left = '0px';
menu.style.left = '-480px';
scope.isMenuOpened = false;
};
element[0].firstChild.onBlurEvent = scope.onViewOut;
element[0].firstChild.onFocusEvent = scope.onViewOver;
};
//-------------------------
// TEMPLATE
//-------------------------
var componentTemplate = '<div class="navmenu-wrapper">' +
'<div id="navmenu" class="fl-container navmenu navmenu-fixed-left fl-fixed-container">'+
'<div>'+
'<ul>' +
'<fl-nav-menu-item ng-repeat="buttonData in buttonsData" nav-item-data="buttonData" class="text - center" id="ID{{$index}}"></fl-nav-menu-item>' +
'</ul>'+
'<ul class="navmenu-nav-icons">' +
'<div ng-repeat="navButton in navButtons" class="navmenu-nav-icon">' +
'<img ng-src="{{navButton.imgUrl}}">' +
'<span>{{navButton.label | i18n }}</span>' +
'</div>' +
'</ul>'+
'</div>'+
'<div>'+
'</div>'+
'</div>'+
'<img src="./images/btn_drawer_menu.png" class="navmenu-tongue" id="navmenu-tongue">' +
'</div>';
//-------------------------
// RETURN
//-------------------------
return {
restrict: "E",
controller: ["$scope", "$element", '$state', 'localize', '$stateParams', 'UplayTracking', 'StateManager', componentController],
link: componentLink,
template: componentTemplate,
replace:true
}
}]);
You can see in the componentLink method that we had manually methods for onFocus/onBlur event:
element[0].firstChild.onBlurEvent = scope.onViewOut;
element[0].firstChild.onFocusEvent = scope.onViewOver;
The problem is : if I change the template of this directive for a templateUrl (so put all html in a separate file), when the onBlur/onFocus event are raised, our methods are not called. Do you have an idea why ? Thanks for your help !
-We use templateCache to loading our html template.
-I already verify if my element[0] is the same with ou without templateUrl and yes it's the same element.

reset star rating after submit in angularjs

Hi I am using star rating option with form submit using angularjs like in the following jsfiddle
<http://jsfiddle.net/manishpatil/2fahpk7s/>
all are working fine.
But I want to reset star rating to default after submit form.
anyone can help me to achieve this?
please refer my code how I implement this star rating
HTML:
Controller:
function socialPostCtrl(socialPostService, userPersistenceService, $location, $sce) {
var socialPostVM = this;
socialPostVM.maxRating = 5;
socialPostVM.clickstar = function (param) {
socialPostVM.rating = param ;
};
//submit post function
socialPostVM.addpost = function () {
angular.element(document.getElementById('addPostBtn'))[0].disabled = true;
var result = socialPostService.addpost(socialPostVM.loggedUserDetails.UserId, socialPostVM.takeawayGuid, socialPostVM.newpost, socialPostVM.attachment, socialPostVM.rating).then(function (response) {
if (response.Success) {
var newpost = {};
newpost.postid = response.SocialPost.SocialPostId;
newpost.postGuid = response.SocialPost.SocialPostGuid;
newpost.profilepic = "";
newpost.postby = response.SocialPost.PostUser;
newpost.postbyid = response.SocialPost.UserId;
newpost.poston = response.SocialPost.PostDate;
newpost.posttext = response.SocialPost.PostContent;
newpost.hasliked = response.SocialPost.HasLiked
newpost.totallikes = 0;
newpost.comments = [];
newpost.totalcomments = 0;
newpost.showcommentbox = false;
newpost.candeletepost = function () { return true; }
newpost.hasAttachment = response.SocialPost.HaveMedia;
if (response.SocialPost.HaveMedia) {
newpost.postattachment = $sce.trustAsResourceUrl(response.SocialPost.PostMedia.MediaFileName);
}
newpost.rating = socialPostVM.rating / socialPostVM.maxRating * 100;
socialPostVM.socialposts.splice(0, 0, newpost);
}
}).finally(function () {
socialPostVM.attachment = [];
angular.element(document.getElementById('addPostBtn'))[0].disabled = false;
angular.element(document.getElementById('posttext'))[0].value = "";
socialPostVM.filelist = [];
});
};
Directive:
angular.module("test").directive('starRating', function () {
return {
restrict: 'E',
scope: {
rating: '=',
maxRating: '#',
readOnly: '#',
click: "&"
},
template: "<div style='display: inline-block; margin: 0px; padding: 0px; cursor:pointer;' ng-repeat='idx in maxRatings track by $index'> \
<img ng-src='{{((hoverValue + _rating) <= $index) && \"/images/star-empty-lg.png\" || \"/images/star-fill-lg.png\"}}' \
ng-Click='isolatedClick($index + 1)' \
ng-mouseenter='isolatedMouseHover($index + 1)' \
ng-mouseleave='isolatedMouseLeave($index + 1)'></img> \
</div>",
compile: function (element, attrs) {
if (!attrs.maxRating || (Number(attrs.maxRating) <= 0)) {
attrs.maxRating = '5';
};
},
controller: function ($scope, $element, $attrs) {
$scope.maxRatings = [];
for (var i = 1; i <= $scope.maxRating; i++) {
$scope.maxRatings.push({});
};
$scope._rating = $scope.rating;
$scope.isolatedClick = function (param) {
if ($scope.readOnly == 'true') return;
$scope.rating = $scope._rating = param;
$scope.click({
param: param
});
};
}
}
});
Thanks
you need more info here.
on the function you call for submit you will need to reset the value to their default.
$scope.submit = function(data){
//do something with data
//reset values back to defualt
$scope.starRating1 = 4;
$scope.starRating2 = 5;
$scope.starRating3 = 2;
$scope.hoverRating1 = $scope.hoverRating2 = $scope.hoverRating3 = 0;
};

How to get selected value from ng-autocomplete directive to controller

I am using a directive for auto complete / auto suggest in angular Js taken from http://demo.jankuri.com/ngAutocomplete/. It is working fine getting the data from server and filtering it. But I am facing problem into select and use that select item from the auto complete.
Here is the code of directive what I am using for this...
app.factory('ngAutocompleteService', ['$http', function($http)
{
var self = this;
self.getData = function (url, keyword) {
return $http.get(url, { query: keyword });
};
return self;
}])
app.directive('ngAutocomplete', ['$timeout','$filter','ngAutocompleteService',
function($timeout, $filter, ngAutocompleteService)
{
'use strict';
var keys = {
left : 37,
up : 38,
right : 39,
down : 40,
enter : 13,
esc : 27
};
var setScopeValues = function (scope, attrs) {
scope.url = base_url+attrs.url || null;
scope.searchProperty = attrs.searchProperty || 'skills';
scope.maxResults = attrs.maxResults || 10;
scope.delay = parseInt(attrs.delay, 10) || 300;
scope.minLenth = parseInt(attrs.minLenth, 10) || 2;
scope.allowOnlyResults = scope.$eval(attrs.allowOnlyResults) || false;
scope.placeholder = attrs.placeholder || 'Search...';
};
var delay = (function() {
var timer = 0;
return function (callback, ms) {
$timeout.cancel(timer);
timer = $timeout(callback, ms);
};
})();
return {
restrict: 'E',
require: '?ngModel',
scope: true,
link: function(scope, element, attrs, ngModel) {
setScopeValues(scope, attrs);
scope.results = [];
scope.currentIndex = null;
scope.getResults = function () {
if (parseInt(scope.keyword.length, 10) === 0) scope.results = [];
if (scope.keyword.length < scope.minLenth) return;
delay(function() {
ngAutocompleteService.getData(scope.url, scope.keyword).then(function(resp) {
scope.results = [];
var filtered = $filter('filter')(resp.data, {skills: scope.keyword});
for (var i = 0; i < scope.maxResults; i++) {
scope.results.push(filtered[i]);
}
scope.currentIndex = 0;
if (scope.results.length) {
scope.showResults = true;
}
});
}, scope.delay);
};
scope.selectResult = function (r) {
scope.keyword = r.skills;
ngModel.$setViewValue(r.skills);
scope.ngModel = r.skills;
ngModel.$render();
scope.showResults = false;
};
scope.clearResults = function () {
scope.results = [];
scope.currentIndex = null;
};
scope.hoverResult = function (i) {
scope.currentIndex = i;
}
scope.blurHandler = function () {
$timeout(function() {
if (scope.allowOnlyResults) {
var find = $filter('filter')(scope.results, {skills: scope.keyword}, true);
if (!find.length) {
scope.keyword = '';
ngModel.$setViewValue('');
}
}
scope.showResults = false;
}, 100);
};
scope.keyupHandler = function (e) {
var key = e.which || e.keyCode;
if (key === keys.enter) {
scope.selectResult(scope.results[scope.currentIndex]);
}
if (key === keys.left || key === keys.up) {
if (scope.currentIndex > 0) {
scope.currentIndex -= 1;
}
}
if (key === keys.right || key === keys.down) {
if (scope.currentIndex < scope.maxResults - 1) {
scope.currentIndex += 1;
}
}
if (key === keys.esc) {
scope.keyword = '';
ngModel.$setViewValue('');
scope.clearResults();
}
};
},
template:
'<input type="text" class="form-control" ng-model="keyword" placeholder="{{placeholder}}" ng-change="getResults()" ng-keyup="keyupHandler($event)" ng-blur="blurHandler()" ng-focus="currentIndex = 0" autocorrect="off" autocomplete="off">' +
'<input type="hidden" ng-model="skillIdToBeRated">'+
'<div ng-show="showResults">' +
' <div ng-repeat="r in results | filter : {skills: keyword}" ng-click="selectResult(r)" ng-mouseover="hoverResult($index)" ng-class="{\'hover\': $index === currentIndex}">' +
' <span class="form-control">{{ r.skills }}</span>' +
' </div>' +
'</div>'
};
}]);
I am unable to get value which is selected by ng-click="selectResult(r)" function. The value is showing into text field but not getting it into controller.
I was also using the same directive for showing the auto complete text box. I have tried the following for getting the selected value from auto complete.
in HTML
<div ng-controller="Cntrl as cntrl">
<ng-autocomplete ng-model="cntrl.selectedValue" url="url" search-property="keyword" max-results="10" delay="300" min-length="2" allow-only-results="true"></ng-autocomplete>
</div>
in JavaScript
app.controller('Cntrl', function($scope, $http) {
var self = this;
self.selectedValue = '';
$scope.getSelectedValue = function(){
console.log(self.selectedValue);
}
});
I hope this may help you.
I ran into the same issue. I ended up just watching the property from the details attribute in the ng-autocomplete input and it works pretty well.
$scope.$watch(function() {
return vm.location_result;
}, function(location) {
if (location) {
vm.location_list.push(location);
vm.location = '';
}
});
Fiddle Example: http://jsfiddle.net/n3ztwucL/
GitHub Gist: https://gist.github.com/robrothedev/46e1b2a2470b1f8687ad

why does datepicker popup not display?

I am trying to create a bootstrap datapicker directive:
app.directive('datePicker', function ($compile, $timeout) {
return {
replace: true,
restrict:'E',
templateUrl: 'datepicker.html',
scope: {},
controller: function ($scope) {
console.log('datepciker');
// debugger;
$scope.today = function () {
$scope.dt = new Date();
};
$scope.today();
$scope.clear = function () {
$scope.dt = null;
};
// Disable weekend selection
//$scope.disabled = function(date, mode) {
// return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
//};
$scope.toggleMin = function () {
$scope.minDate = $scope.minDate ? null : new Date();
};
$scope.toggleMin();
$scope.open = function ($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
};
//$scope.open = function ($event) {
// $scope.status.opened = true;
//};
$scope.dateOptions = {
formatYear: 'yy',
startingDay: 1
};
$scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
$scope.format = $scope.formats[0];
$scope.status = {
opened: false
};
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
var afterTomorrow = new Date();
afterTomorrow.setDate(tomorrow.getDate() + 2);
$scope.events =
[
{
date: tomorrow,
status: 'full'
},
{
date: afterTomorrow,
status: 'partially'
}
];
$scope.getDayClass = function (date, mode) {
if (mode === 'day') {
var dayToCheck = new Date(date).setHours(0, 0, 0, 0);
for (var i = 0; i < $scope.events.length; i++) {
var currentDay = new Date($scope.events[i].date).setHours(0, 0, 0, 0);
if (dayToCheck === currentDay) {
return $scope.events[i].status;
}
}
}
return '';
};
}
};
In my page I have:
<date-picker ng-model="dateTo"></date-picker>
For some reason the popup does not come up, any suggestions on how to fix this?
plunkr:http://plnkr.co/edit/UiMiEk5GQSVId4YdAnCH?p=preview
Line 2 of datepicker.html ends in
is-open="status.opened"
If you change that to just is-open-"opened" you get a date picker.

scope.$on() invokes several times for one broadcast

In Angular.js, scope.$on("UPDATE", function(event, account, vipLabel, nodeName) is firing about 20 times when it should only invokes once for each $rootScope.$broadcast("UPDATE", this.account,this.vipLabel, this.nodeName). I know that scope.$on() contains an event object, but I haven't been able to find a use for it to help my issue.
I am stuck on this and I need the scope.$on() to fire only once for each broadcast.
angular.module('main.vips')
.factory("StatusTrackerService", function($timeout, $rootScope, Restangular) {
var CHECK_ITERATIONS = 1;
var TIME_ITERATION = 1000;
var eventCollection = {};
eventCollection.vipLabel;
function urlBuilder(account, eventId) {
var account = Restangular.one("account", account);
var eventId = account.one("event", eventId);
return eventId;
}
function NewStatusEvent(account, eventId, url, vipLabel, nodeName) {
this.iteration = 0;
this.account = account;
this.eventId = eventId;
this.url = url;
this.vipLabel = vipLabel;
this.nodeName = nodeName;
}
NewStatusEvent.prototype.runCheckLoop = function() {
this.url.get()
.then(function(data) {
if (data.Automation.Status != "SUCCESS") {
console.log("yes");
console.log(this.iteration);
console.log(CHECK_ITERATIONS);
if (this.iteration < CHECK_ITERATIONS) {
this.iteration++;
$rootScope.$broadcast("UPDATE", this.account,
this.vipLabel, this.nodeName);
console.log('-------------------');
console.log('checking ' + JSON.stringify(this.url));
console.log('iteration ' + this.iteration);
console.log('-------------------');
$timeout(function (){
this.runCheckLoop();
}.bind(this), TIME_ITERATION);
}
}
}.bind(this));
}
function runEventCheck(account, eventId, nodeName) {
url = urlBuilder(account, eventId);
eventCollection[eventCollection.vipLabel] = new NewStatusEvent(account, eventId,
url, eventCollection.vipLabel, nodeName);
eventCollection[eventCollection.vipLabel].runCheckLoop();
}
return { runEventCheck: runEventCheck,
eventCollection: eventCollection
};
});
Directive:
return {
templateUrl: "vips/directives/action_button.html",
restrict: "AE",
replace: true,
transclude: false,
scope: {
label: "#?",
icon: "#?",
type: "#?",
actions: "=?"
},
link: function(scope, element, attrs) {
element.on("click", function(event) {
var vipLabel = event.currentTarget.id;
StatusTrackerService.eventCollection.vipLabel = vipLabel;
});
scope.$on("UPDATE", function(event, account,
vipLabel, nodeName) {
console.log("Scope.on has fired this many times");
var nodeSelector = "#node-"+vipLabel+"-"+nodeName;
var nodeElement = angular.element(document.querySelector(nodeSelector));
if (!nodeElement.length) {
var vipElement = angular.element(document.querySelector('#vipLabel-'+vipLabel));
var elementGlobe = '<div id="'+vipLabel+nodeName+'">Element modified</div>';
vipElement.append(elementGlobe);
}
});
return scope.actions = services[attrs.type];
}
}
});
Logged output:
21 -Scope.on has fired this many times actionButton.js:52
------------------- status-checker.js:35
checking {"id":"0fd6afd9-2367-4a0-a5c9-ff0b3e60cdcf","route":"event","reqParams":null,"$fromServer":false,"parentResource":{"route":"account","parentResource":null,"id":"99006"},"restangularCollection":false} status-checker.js:36
iteration 1 status-checker.js:37
-------------------
Html:
<div action-button type="loadbalancer" label="Actions" icon="glyphicon glyphicon-cog"
actions="actions.loadbalancer"></div>
</div>
<div id="{{vip.label}}" action-button type="vip" icon="glyphicon glyphicon-pencil" actions="actions.vips"
class="pull-right"></div>
<div action-button type="node" icon="glyphicon glyphicon-pencil" actions="actions.nodes"
class="pull-right"></div>
UPDATE:
I added if (scope.type !== "vip") and it worked...now the event fires only once. It doesn't make sense to me because it is the <div id="{{vip.label}}" action-button type="vip" that I am using. It seems like it should be if (scope.type == "vip") instead...but it's the opposite.
scope.$on("UPDATE", function(event, account,
vipLabel, nodeName) {
if (scope.type !== "vip") {
console.log(scope);
var nodeSelector = "#node-"+vipLabel+"-"+nodeName;
var nodeElement = angular.element(document.querySelector(nodeSelector));
console.log(nodeElement.length);
if (nodeElement.length == 0) {
console.log("create node");
var vipElement = angular.element(document.querySelector('#vipLabel-'+vipLabel));
var elementGlobe = '<div id="'+vipLabel+nodeName+'">Element modified</div>';
vipElement.append(elementGlobe);
}
}
});

Resources