I have a directive and I need to give her a setting to change my view based on this parameter.
<ta-card type="unlock"
class="parent-card"
owner="currentUser"
ng-repeat="unlockCard in unlockedCards"
title="{{unlockCard.title}}">
</ta-card>
Here i send param title and i want recup here
<div class="card-footer">
<div class="card-info left floated">
<div class="info" ng-model="title"></div>
<span class="sub-info"
ng-if="$root.response==undefined">Chargement</span>
<span class="sub-info" translate="card.subtitle.soon_available" ng-if="$root.response!=undefined"></span>
</div>
<span class="flip-btn white"
ng-if="options.flip"
ng-click="flipCard(model.parentId != undefined)">
<i class="chevron right icon"></i></span>
</div>
</div>
Edit :
That's my directive, but i'm not sure that could be help you
.directive('taCard', ['appAuth', 'taCardService', '$rootScope', '$timeout',
function (appAuth, taCardService, $rootScope, $timeout) {
return {
restrict: 'E', // cards must be always an element, by convention
transclude: false,
replace: true,
scope: {
owner: '=?', //this is going to be an User Object
model: '=?',
readonly: '=?', //this makes form fields readonly,
transcludeData: '=?',
childLoad: '#',
unlockType: '#'
},
link: function (scope, element, attrs) {
// console.log(scope.model);
console.log(scope);
scope.showFront = true;
scope.displayChildCards = false;
scope.elementId = 'card-' + parseInt(Math.random() * 100000000000);
element.attr('id', scope.elementId);
scope.isEditable = false;
scope.options = taCardService.getOptions(attrs.type);
// console.log(scope.options);
scope.model = angular.isDefined(scope.model) ? scope.model : {};
if (scope.options.hasOwner) {
taCardService.hasAccess(scope.owner)
.then(function (access){
if (access === true) {
//set if is editable
appAuth.currentUser()
.then(function (currentUser) {
scope.currentUser = currentUser;
if (scope.owner.id === scope.currentUser.id) {
scope.isEditable = true;
}
});
} else {
// destroy the card if user doesn't have acccess
element.remove();
scope.$destroy();
}
});
}
if (taCardService.hasService(attrs.type)) {
taCardService.onLoad(attrs.type, scope, element);
taCardService.setEvents(attrs.type, scope);
scope.service = taCardService.getService(attrs.type);
}
// get the model data
if (taCardService.hasService(attrs.type)) {
taCardService.getModel(attrs.type, scope)
.then(function (data) {
scope.model.data = data.model;
},
function (error) {
console.log('impossible to get the model: status ' + error.status);
});
}
if (!angular.isDefined(scope.owner) && scope.options.hasOwner) {
// alert to the sleepy developer that must pass the owner
console.log('hey! you forgot the owner!');
return;
}
}
}
}
])
My factory
window.angular && (function(angular) {
'use strict';
angular.module('taApp')
.factory('taUnlockCard', ['$q','$rootScope', function($q,$rootScope) {
// JE RECUPERE LE TITRE DE LA CARTE ???
$rootScope.title="Titre";
return {
};
}]);
})(window.angular); // jshint ignore:line
Related
Edit: I have added the details as well.
I could do with some help with passing the value selected in my directive to my controller $scope.
I have a very basic directive that I want to place within another directive, but the value does not get passed to the controller scope. I get an "undefined" value for my parameter.
However, when I place the little directive anywhere in the view's HTML, and not within the other directive's tags, it works.
This is my new directive:
(function () {
'use strict';
angular.module('portalDashboardApp')
.directive('ogItemsPerPage', function () {
return {
restrict: 'E',
replace: true,
templateUrl: './tpls/ItemsPerPageTemplate.html',
scope: {
perPageCountOptions: [30, 50, 100, "ALL"],
selectedItemsPerPage: '#'
}
};
});
})();
This is the template:
<div>
<div id="DropDownBox">
<label for="ItemsPerpage">Items per Page: </label>
<select ng-change="changePageCount()" ng-model="selectedItemsPerPage" id="ItemsPerpage" ng-options="perPage for perPage in perPageCountOptions"></select>
</div>
</div>
This is the function called in my controller:
$scope.changePageCount = function () {
if ($scope.selectedItemsPerPage === "ALL") {
$scope.perPageCount = -1;
}
else {
$scope.perPageCount = $scope.selectedItemsPerPage;
}
pullSocialData();
}
This is the view where I am placing my <og-items-per-page> directive, inside the tags of another directive:
<og-data-box heading="Tweet List" link="" uid="socialMentionsMeta" description="">
<div class="dataStatus">
{{dataStatus}}
<og-loading-indicator></og-loading-indicator>
</div>
<og-items-per-page></og-items-per-page>
<div class="dataContent" ng-show="dataContent" ng-mouseover="showGraphTrainingInfo()">
<og-social-media-mentions-list></og-social-media-mentions-list>
<div ng-show="showMorePostLoading" id="morePostLoadingContainer"><div id="morePostLoadingInner"></div></div>
</div>
</og-data-box>
The data-box directive:
(function () {
'use strict';
angular.module('portalDashboardApp')
.directive('ogDataBox', function () {
return {
restrict: 'E',
transclude: true,
replace: true,
scope: {
heading: '#',
link: '#',
uid: '#',
description: '#',
chartConfig: '#'
},
link: function (scope) {
scope.boxOpenCloseTitle = 'Collapse';
scope.iconStatus = 'upIcon';
scope.contentStatus = '';
var openCloseStatus = true;
var maximumSize = false;
scope.dataBoxUnderlayClass = '';
scope.dataBoxMaxMinClass = '';
scope.maxMinIcon = 'maximise';
scope.openCloseDataBox = function () {
if (openCloseStatus) {
scope.boxOpenCloseTitle = 'Expand';
openCloseStatus = false;
scope.iconStatus = 'downIcon';
scope.contentStatus = 'hideContent';
}
else {
scope.boxOpenCloseTitle = 'Collapse';
openCloseStatus = true;
scope.iconStatus = 'upIcon';
scope.contentStatus = '';
}
};
scope.maxMinDatabox = function () {
maximumSize = !maximumSize;
if (maximumSize) {
scope.dataBoxUnderlayClass = 'dataBoxUnderlayFullScreen';
scope.dataBoxMaxMinClass = 'dataBoxMaximised';
scope.maxMinIcon = 'minimise';
}
else {
scope.dataBoxUnderlayClass = '';
scope.dataBoxMaxMinClass = '';
scope.maxMinIcon = 'maximise';
}
};
},
templateUrl: './tpls/DataBoxTemplate.html'
};
});
})();
The data-box template:
<div ng-class="dataBoxUnderlayClass">
<section class="dataBox" id="{{uid}}" ng-class="dataBoxMaxMinClass">
<header class="dataBoxHeader">
{{heading}}
<img src="images/openCloseIcon.svg" title="{{boxOpenCloseTitle}}" width="15" height="15" class="openCloseBox {{iconStatus}}" ng-click="openCloseDataBox()" />
<img ng-mouseover="infoIconStyle='dataBoxInfoContentShow'" ng-mouseleave="infoIconStyle='dataBoxInfoContentHide'" src="images/info-icon.svg" height="15" class="dataBoxInfo" />
</header>
<div class="dataBoxContent {{contentStatus}}">
<div ng-class="infoIconStyle" class="dataBoxInfoContent">{{description}}</div>
<div ng-transclude></div>
</div>
</section>
</div>
What do I need to change so that I can nest my directive within other directives if I want to?
Thank you!
The problem comes from the isolated scope created by your directive.
The html inside og-data-box is under the directive scope and can't access to the controller scope.
As it is describe in this article http://angular-tips.com/blog/2014/03/transclusion-and-scopes/ if you want to access your controller scope inside <og-data-box></og-data-box> you need to append it to your isolated scope.
Something like that should correct your problem
app.directive('og-data-box', function() {
return {
restrict: 'EA',
scope: {
heading: '=',
link: '=',
uid: '=',
description: '='
},
transclude:true,
link: function(scope, element, attrs, ctrl, transclude) {
transclude(scope.$parent, function(clone, scope) {
element.append(clone);
});
}
};
});
EDIT :
As it is mentioned in the comment this is not the best way to do it.
You should pass your scope to the scope of og-data-box then you can use it in the nested directive :
og-data-box (I add selectedItemsPerPage to the scope)
(function () {
'use strict';
angular.module('portalDashboardApp')
.directive('ogDataBox', function () {
return {
restrict: 'E',
transclude: true,
replace: true,
scope: {
heading: '#',
link: '#',
uid: '#',
description: '#',
chartConfig: '#',
selectedItemsPerPage: '#'
},
link: function (scope) {
scope.boxOpenCloseTitle = 'Collapse';
scope.iconStatus = 'upIcon';
scope.contentStatus = '';
var openCloseStatus = true;
var maximumSize = false;
scope.dataBoxUnderlayClass = '';
scope.dataBoxMaxMinClass = '';
scope.maxMinIcon = 'maximise';
scope.openCloseDataBox = function () {
if (openCloseStatus) {
scope.boxOpenCloseTitle = 'Expand';
openCloseStatus = false;
scope.iconStatus = 'downIcon';
scope.contentStatus = 'hideContent';
}
else {
scope.boxOpenCloseTitle = 'Collapse';
openCloseStatus = true;
scope.iconStatus = 'upIcon';
scope.contentStatus = '';
}
};
scope.maxMinDatabox = function () {
maximumSize = !maximumSize;
if (maximumSize) {
scope.dataBoxUnderlayClass = 'dataBoxUnderlayFullScreen';
scope.dataBoxMaxMinClass = 'dataBoxMaximised';
scope.maxMinIcon = 'minimise';
}
else {
scope.dataBoxUnderlayClass = '';
scope.dataBoxMaxMinClass = '';
scope.maxMinIcon = 'maximise';
}
};
},
templateUrl: './tpls/DataBoxTemplate.html'
};
});
})();
And then when you call all the directive :
<og-data-box heading="Tweet List" link="" uid="socialMentionsMeta" description="" selected-items-per-page="selectedItemsPerPage">
<div class="dataStatus">
{{dataStatus}}
<og-loading-indicator></og-loading-indicator>
</div>
<og-items-per-page selected-items-per-page="selectedItemsPerPage"></og-items-per-page>
<div class="dataContent" ng-show="dataContent" ng-mouseover="showGraphTrainingInfo()">
<og-social-media-mentions-list></og-social-media-mentions-list>
<div ng-show="showMorePostLoading" id="morePostLoadingContainer"><div id="morePostLoadingInner"></div></div>
</div>
</og-data-box>
I currently have a directive that is called whenever a click event happens. This helps me change the icon for adding to user's favorite list.
View:
<div class="col col-33">
<i class="icon ion-ios-heart-outline" favorite="place[0].objectId" on-icon="ion-ios-heart-outline" off-icon="ion-ios-heart" icon-switcher /></i>{{place[0].likes}}
</div>
Directive:
.directive('iconSwitcher', function() {
return {
restrict : 'A',
scope: {
favorite: '='
},
link : function(scope, elem, attrs, PlaceService, ) {
var currentState = true;
elem.on('click', function() {
console.log('objectId',scope.favorite);
if(currentState === true) {
angular.element(elem).removeClass(attrs.onIcon);
angular.element(elem).addClass(attrs.offIcon);
} else {
angular.element(elem).removeClass(attrs.offIcon);
angular.element(elem).addClass(attrs.onIcon);
}
currentState = !currentState
});
}
};});
I will like to call a service from this directive when the click event happens like i do from a controller. Here is a sample of the service i want to call
$scope.addFavorite = function(objectId){
PlaceService.addFavorite(objectId,currentUser)
Angular will not inject the service into the link function.Inject your service in the directive and use like in the controller.
.directive('iconSwitcher', ['PlaceService', function(PlaceService) {
// Use PlaceService here as a simple service
return {
restrict : 'A',
scope: {
favorite: '='
},
link : function(scope, elem, attrs) {
var currentState = true;
elem.on('click', function() {
console.log('objectId',scope.favorite);
if(currentState === true) {
angular.element(elem).removeClass(attrs.onIcon);
angular.element(elem).addClass(attrs.offIcon);
} else {
angular.element(elem).removeClass(attrs.offIcon);
angular.element(elem).addClass(attrs.onIcon);
}
currentState = !currentState;
})
};
]})
Angular don't inject dependencies in the link function, you have to take it in the function declaration of the directive itself :
angular.directive('myDirective', function(myService) {
return {
// ...
link: function(...) {
myService.addFavorite(objectId, currentUser);
}
}
});
I have a widget like directive called waComments, it loads components via a RESTful service and displays them. In my view I'm using ng-repeat to loop over them and to render them with a button that if pressed Shows a new reply to form. This his handled by the waCommentsReply directive. One waComments widget has many child directives of type waCommentsReply. When the form is filled and submitted I want to add the new comment on top of my comments list. So both directives have to share the comments data.
I've tried to implement this here Sharing data between directives but without much success, the comment data is not updated when I add a new comment. I see that the RESTful API calls work and the data is returned, so this is not an issue.
Why is my implementation of Sharing data between directives not working in my case?
waCommentsReply directive:
waFrontend.directive('waCommentsReply', ['$rootScope', 'Comment', 'WaFormValidation', 'WaCommentStore', function($rootScope, Comment, WaFormValidation, WaCommentStore) {
return {
restrict: 'E',
templateUrl: '/stubs/comment-form.html',
transclude: true,
scope: {
replyTo: '#replyTo',
replyFormList: '=replyFormList',
loggedIn: '#loggedIn',
model: '#model',
id: '#id',
cancelButton: '#cancelButton'
},
controller: function($scope) {
$scope.comments = WaCommentStore;
if ($scope.cancelButton == undefined) {
$scope.cancelButton = true;
} else {
$scope.cancelButton = false;
}
$scope.comment = $scope.commentForm = {
Comment: {
author_name: '',
body: '',
model: $scope.model,
foreign_key: $scope.id,
parent_id: $scope.replyTo
}
};
$scope.$watch('replyFormList', function (newValue, oldValue) {
if (newValue) {
$scope.replyFormList = newValue;
}
});
if ($scope.loggedIn == undefined) {
$scope.loggedIn = false;
}
/**
* Handles the submission and response of a reply
*
* #return void
*/
$scope.reply = function() {
Comment.add($scope.comment).then(function(result) {
if (result.status == 'fail' || result.validation != undefined) {
$scope.validationErrors = result.validation;
WaFormValidation.validate(result.validation, $scope.commentForm);
} else if (result.status == 'success') {
//$scope.$parent.comments.unshift(result.data.comment);
//$scope.comments.unshift(result.data.comment);
$scope.comments.comments.unshift(result.data.comment);
//WaCommentStore.append($scope.model, $scope.id, result.data.comment);
$scope.comments, $scope.id, result.data.comment
$scope.comment = {};
$scope.replyFormList[$scope.replyTo] = false;
}
});
};
$scope.close = function() {
$scope.comment = {};
if ($scope.replyFormList[$scope.replyTo] != undefined) {
$scope.replyFormList[$scope.replyTo] = false;
}
}
}
};
}]);
WaCommentStore directive:
waFrontend.factory('WaCommentStore', function() {
return {
comments: []
};
});
waComments directive:
waFrontend.directive('waComments', ['$rootScope', 'Comment', 'WaCommentStore', function($rootScope, Comment, WaCommentStore) {
return {
restrict: 'E',
templateUrl: '/stubs/comments.html',
scope: {
model: '#commentModel',
id: '#commentFk'
},
controller: function($scope) {
$scope.comments = WaCommentStore;
$scope.loaded = false;
$scope.loadedMore = true;
$scope.currentPage = 1;
$scope.loggedIn = false;
$scope.paging = {};
$scope.replyFormList = {};
Comment.comments($scope.model, $scope.id).then(function(result) {
$scope.comments.comments.push.apply($scope.comments.comments, result.data.comments);
$scope.loggedIn = result.data.loggedIn;
$scope.paging = result.paging.Comment;
$scope.loaded = true;
});
$scope.loadMore = function() {
$scope.loadedMore = false;
if ($scope.paging.nextPage == false) {
//return false;
}
var options = {
page: $scope.paging.page + 1
};
Comment.comments($scope.model, $scope.id, options).then(function(result) {
$scope.comments.comments.push.apply($scope.comments.comments, result.data.comments);
$scope.paging = result.paging.Comment;
$scope.loadedMore = true;
});
};
$scope.submitComment = function() {
//alert($scope.author_name + $scope.body);
};
$scope.reply = function(replyId) {
$scope.replyFormList[replyId] = true;
}
}
};
}]);
since in both directive you defined scope: {} basically it means you defined those directives to use isolated scope.
with isolated scope, a scope/directive can't see what is in the parent scope.
however parent scope, can be affected by the child scope changes with 2 way binding definition.
https://docs.angularjs.org/guide/scope
try changing the shared data like this
waFrontend.factory('WaCommentStore', function() {
var comments = [];
var getComments = function() { return comments; }
var setComments = function(data) { comments = data; }
return {
getComments : getComments ,
setComments : setComments
};
});
I wanted to put it as a comments, but it would have been difficult to understand for you.
Please let me know if this works, else I will delete this answer.
I write a directive to impl ng-disabled because i just can use angularjs which version is 1.1.5,it't not provide ng-disabled,so
tableApp.directive('myDisabled', function($compile) {
return {
restrict: 'A',
replace: true,
scope: {
myDisabled: '='
},
link: function(scope, element, attrs) {
var test = scope.$eval(attrs.myDisabled);
console.log(test);
scope.$watch(attrs.myDisabled, function (test) {
if (test) {
element.attr();
}
else {
element.attr('disabled', 'false');
}
});
}
};
});
the html code:
<html ng-app="tableApp">
<head></head>
<body>
<div ng-controller="TableCtrl">
<input ng-model="page"/>
<button class="btn btn-primary" ng-click="previouspage()" my-disabled="page <=1">上一页</button>
</div>
</body>
</html>
but why i click this button,it can't call the function previouspage()
this is my angularjs code
var tableApp = angular.module('tableApp', [], function ($httpProvider) {
$httpProvider.defaults.headers.post['Content-Type'] =
'application/x-www-form-urlencoded;charset=utf-8';
});
tableApp.directive('myDisabled', function($compile) {
return {
restrict: 'A',
replace: true,
scope: {
myDisabled: '='
},
link: function(scope, element, attrs) {
var test = scope.$eval(attrs.myDisabled);
console.log(test);
scope.$watch(attrs.myDisabled, function (test) {
if (test) {
element.attr();
}
else {
element.attr('disabled', 'false');
}
});
$compile(attrs);
}
};
});
tableApp.controller('TableCtrl', function ($scope, $http) {
$scope.page = 1;
$scope.getCr = function getCr(later) {
var url = '/cms/copyright/find';
var request = $http({
method: 'get',
url: url,
params: {
page_length: 25,
start: ($scope.page - 1) * 25,
s: ''
}
});
request.then(function (data) {
if (data.data.result == 'OK') {
console.log(data.data);
$scope.copyright = data.data;
if (later != undefined) {
later();
}
}
});
};
$scope.nextpage = function nextpage() {
$scope.page += 1;
$scope.getCr();
};
$scope.onepage = function onepage() {
$scope.page = 1;
$scope.getCr();
};
$scope.previouspage = function previouspage() {
$scope.page -= 1;
$scope.getCr();
};
$scope.setPos = function setPos(index, holder_id) {
var pos = window.prompt("请输入排序位置", $scope.copyright.items[index].pos);
console.log(pos);
if (pos != null && pos != "" && parseInt(pos) > 0) {
var a = 'holder_id=' + holder_id + '&pos=' + pos;
$http.post('/cms/copyright/top', a).then(function (data) {
data = data.data;
if (data.result == 'OK') {
$scope.getCr(function () {
$scope.copyright.items[index].change = true;
});
} else {
alert(data.result);
}
});
}
console.log($scope.copyright.items[index]);
};
$scope.getCr();
});
Your problem is related to $scope.
When you are explicitly creating an isolated scope in your directive (using scope: {}) you can't access parent scope directly. If you don't, there is no problem doing so.
So, in short, just change ng-click="previouspage()" to ng-click="$parent.previouspage()" inside your HTML template.
Related plunker here: http://plnkr.co/edit/WRflPF
You could also refactor your directive's link function and remove unnecessary properties. So directive could be:
app.directive('myDisabled', function () {
return {
restrict: 'A',
scope: {
myDisabled: '='
},
link: function(scope, element) {
scope.$watch('myDisabled', function (val) {
element.attr('disabled', val);
});
}
};
});
The problem is the directive scope. You try to access an scope variable from parent scope (your controllers scope)
If you disable the isolate scope for your directive it works
For example:
tableApp.directive('myDisabled', function($compile) {
return {
restrict: 'A',
replace: true,
scope: {
myDisabled: '='
},
link: function(scope, element, attrs) {
var test = scope.$eval(attrs.myDisabled);
console.log(test);
scope.$watch(attrs.myDisabled, function (test) {
if (test) {
element.attr();
}
else {
element.attr('disabled', 'false');
}
});
}
};
});
I'm trying to build real time service messaging with MongoDB and AngularJS. For some reason, when there is new data in my 'messaging' collection, the Messaging.getAllMessages() service is not triggered and my data is not updated in the view, using $watchCollection.
This is in my services.js, the important function is getAllMessages():
angular.module('myApp')
.factory('Messaging', function($resource, $http, $q, $rootScope){
var myData = {};
return {
sendMessage: function(message, success, error) {
$http.post('/api/v1/users/' + message.to.id + '/messages', message).success(function(res) {
toastr.success('Message sent');
}).error(function(error) {
toastr.error("Error on save");
});
},
getAllMessages: function(userId) {
var deferred = $q.defer();
if(!myData) {
deferred.resolve(myData);
} else if (userId && userId !== '') {
$http.get('/api/v1/users/' + userId+ '/messages').success(function(data) {
myData = data;
deferred.resolve(myData);
// update angular's scopes
$rootScope.$$phase || $rootScope.$apply();
});
} else {
deferred.reject();
}
return deferred.promise;
},
markAsRead: function(ids, success, error) {
var deferred = $q.defer();
if(!myData) {
deferred.resolve(myData);
} else if (ids && ids !== '') {
$http.put('/api/v1/users/' + ids.userId + '/messages/' + ids.messageId).success(function(data) {
myData = data;
deferred.resolve(myData);
// update angular's scopes
$rootScope.$$phase || $rootScope.$apply();
});
} else {
deferred.reject();
}
return deferred.promise;
},
getMessage: function(ids, success, error) {
return $http.get('/api/v1/users/' + ids.userId + '/messages/' + ids.messageId);
},
deleteMessage: function(ids, success, error) {
return $http.delete('/api/v1/users/' + ids.userId + '/messages/' + ids.messageId);
}
}
});
This is in directive.js:
angular.module('myApp').directive('messaging', ['$log', 'Messaging', function($log, Messaging){
return {
scope: true,
restrict: 'A', // E = Element, A = Attribute, C = Class, M = Comment
templateUrl: '/views/templates/messaging-dropdown.html',
replace: true,
link: function($scope, iElm, iAttrs, controller) {
Messaging.getAllMessages($scope.user.id).then(function(myData) {
$scope.allMessages = myData;
$scope.newMessages = 0;
$scope.$watchCollection('allMessages', function(newVal, oldVal){
if(newVal !== oldVal) {
$scope.newMessages = 0;
// Count the number of unread messages
for (var i = myData.length - 1; i >= 0; i--) {
if(myData[i].read === false) {
$scope.newMessages++;
}
};
}
}, true);
}, function() {
// request failed (same as 'return false')
$scope.allMessages = 'i got the error';
});
}
};
}]);
And this is the template, messaging-dropdown.html:
<div>
<a ng-click="showMessages()" ng-class="{clicked: messagesToggled}">
<i class="fa fa-envelope"></i>
<span class="badge" ng-show="newMessages > 0">{{newMessages}}</span>
</a>
<ul class="dropdown-menu" ng-show="messagesToggled">
<li ng-repeat="message in allMessages | limitTo: 5 | orderBy:'sent'">
<a ng-href="/users/{{message.to.id}}/messages/{{message._id}}" ng-class="{unread: !message.read}">
<img ng-src="{{message.from.image}}" alt="" class="img-circle">
<span class="body">
<span class="from">{{message.from.name}}</span>
<span class="message">
{{message.text}}
</span>
<span class="time">
<span>{{message.sent}}</span>
</span>
</span>
</a>
</li>
<li class="footer">
<a ng-href="/users/{{user.id}}/messages">See all <b>{{allMessages.length}}</b> messages</a>
</li>
</div>
As you see the $scope.newMessages is not updated by the watch, when there is new data in the array returned by the serive. I'm missing something, is there need for socket.io or Pusher/Pubnub to achieve the desired behaviour? Thanks in advance for any help.
Thanks #Sunil for pointing that out. I originally thought, that $watch() and $watchCollection(), will pull automatically and check the service for new data based on specific interval provided by the $digest() cycle.
I released that my solution needs some kind of trigger, so that the new data to be pulled from the service when available. So I implemented private messaging channels using socket.io for triggering updates on message sent from the other party.
Here is the updated directive:
Updated directive.js:
angular.module('myApp').directive('messaging', ['$log', 'Messaging', 'messagingSocket', function($log, Messaging, messagingSocket){
// Runs during compile
return {
scope: true,
restrict: 'A', // E = Element, A = Attribute, C = Class, M = Comment
templateUrl: '/views/templates/messaging-dropdown.html',
replace: true,
link: function($scope, iElm, iAttrs, controller) {
messagingSocket.emit('setUser', {id: $scope.user.id});
$scope.allMessages = function(){
Messaging.getAllMessages($scope.user.id).then(function(myData) {
$scope.allMessages.messages = myData;
}, function() {
// request failed (same as your 'return false')
$scope.allMessages = 'i got the error';
});
};
$scope.allMessages();
messagingSocket.forward('new message', $scope);
$scope.$on('socket:new message', function (event, data) {
$scope.allMessages();
});
$scope.$watchCollection('allMessages.messages', function(newVal, oldVal){
if(newVal !== oldVal) {
$scope.newMessages = 0;
// Count the number of unread messages
for (var i = $scope.allMessages.messages.length - 1; i >= 0; i--) {
if($scope.allMessages.messages[i].read === false) {
$scope.newMessages++;
}
};
}
}, true);
}
};
}]);