Reputation: 3532
My view in my angular directive does not seem to update when the underlying data changes. I'm not sure if I'm missing a digest cycle or what but I can't seem to figure out what is happening
Directive:
(function(){
'use strict';
angular.module('app').directive('message', Message);
function Message() {
var markup = '<div class="slds">'+
'<div ng-repeat="message in messageController.alerts">'+
'<div class="slds-box slds-theme--{{message.type}}">'+
'<a href="#" class="slds-float--right" ng-show="message.canDismiss"'+
' ng-click="messageController.closeAlert(message)">'+
'Dismiss'+
'</a>'+
'<h2>'+
'{{message.text}}'+
'</h2>'+
'</div>'+
'</div>'+
'</div>';
return {
restrict: 'E',
controllerAs: 'messageController',
controller: 'MessageController',
template: markup,
scope: {}
};
}
})();
Controller:
(function(){
'use strict';
angular.module('app').controller('MessageController', MessageController);
MessageController.$inject = ['messageService'];
function MessageController(messageService) {
var self = this;
self.alerts = messageService.getMessages();
self.closeAlert = function (message) {
messageService.removeMessage(message);
};
}})();
Service:
(function(){
'use strict';
angular.module('app').service('messageService', MessageService);
function MessageService() {
var self = this;
var messages = [];
self.setMessage = function (message, clear){
if (clear === true){
self.clear();
}
messages.push(message);
};
self.getMessages = function(){
return messages;
};
self.removeMessage = function(message){
var messageIndex = messages.indexOf(message);
if(messageIndex !== -1){
messages.splice(messageIndex, 1);
}
};
self.clear = function(){
messages = [];
};
}
})();
I'm letting the messages display be triggered off of an ng-disabled directive on a button so an example usage would be:
<message></message>
<!-- other markup -->
<button type="submit" ng-disabled="!(form.$valid &&
!vm.arePaymentPeriodsExceeded())"
ng-click="vm.saveStream()">
Save
</button>
and then in the page controller
function arePaymentPeriodsExceeded() {
var totalPeriods = calculateTotalPaymentPeriods();
setPaymentExceededError(totalPeriods);
return totalPeriods > vm.loanInfo.loanTerm;
}
function setPaymentExceededError(totalPeriods){
if(totalPeriods > vm.loanInfo.loanTerm) {
if(messageService.getMessages().indexOf(tooManyPaymentsMessage) === -1) {
messageService.setMessage(tooManyPaymentsMessage);
}
} else {
messageService.removeMessage(tooManyPaymentsMessage);
}
}
The behavior is sporadic, sometimes the message directive shows a message and sometimes it does not. The odd thing is the enabling of the button works fine (in other words the method in the controller is being called to enable/disable the button), but the directive binding is not updating. Is there something happening that is "disconnecting" the service, controller, directive?
Upvotes: 2
Views: 85
Reputation: 300
You need to refresh view by calling getMessages() every-time you perform some operation on messages.
self.alerts = messageService.getMessages()
won't update automatically.
Controller:
self.alerts = messageService.obj.messages;
Service:
var obj = {
messages :[]
}
self.clear = function(){
obj.messages.length = 0;
};
Upvotes: 0
Reputation: 1820
When you call messgeService.clear(), you should be using messages.splice(0), as messages = [] points to a new object reference and you will lose any controller reference to the old messages array. messages.splice(0) will clear the array while maintaining the original object reference.
Upvotes: 1