I'm fairly new to AngularJS and it's the first time I'm writing a directive.
I'm trying to make Bootstrap Year Calendar work with AngularJS. It is a jQuery plug-in to show a calendar with appointments.
I've written this directive to create the calendar:
app.directive('calendarScheduler', [function () {
return {
restrict: 'A',
scope: {
calendarData: '='
},
link: function (scope, element, attrs, ctrl) {
element.calendar({
enableRangeSelection: true,
dataSource: scope.calendarData
});
}
}
}]);
The data is passed to the directive from this controller:
var app = angular.module('App', [])
app.controller('UserCtrl', ['$scope',
function($scope) {
$scope.User = {};
$scope.User.eventsData = [];
init();
$scope.User.addData = function(startDate, endDate) {
$scope.User.eventsData.push({
id: 2,
name: 'Apple Special Event',
location: 'San Francisco, CA',
startDate: new Date(2016, 6, 28),
endDate: new Date(2016, 6, 29)
});
};
function init() {
$scope.User.eventsData = [
{
id: 0,
name: 'Google I/O',
location: 'San Francisco, CA',
startDate: new Date(2016, 4, 28),
endDate: new Date(2016, 4, 29)
},
{
id: 1,
name: 'Microsoft Convergence',
location: 'New Orleans, LA',
startDate: new Date(2016, 2, 16),
endDate: new Date(2016, 2, 19)
}
];
}
}]);
And here is the HTML:
<body ng-app="App">
<div ng-controller="UserCtrl">
<div
calendar-scheduler
id="calendar"
class="calendar"
calendar-data="User.eventsData">
</div>
<button data-ng-click="UserHoliday.addData();">Add Data</button>
</div>
</body>
Plunker showing the result
Everything works if the data is passed at the creation of the directive, but if I click the button to add more data to the calendar, it does not update the data shown (It should show one new appointment). This also does not show data loaded using $http. I've tried $scope.$apply() to update the $scope, both on controller and directive, but it throws an error "$apply already in progress".
As I've said, I'm really new to AngularJS, and I don't know how to make this work, or if I'm missing something here.
Hope you can help. Thanks.
You only bind the data once, so it will never update. Instead 'watch' the data collection:
app.directive('calendarScheduler', [function () {
return {
restrict: 'A',
scope: {
calendarData: '='
},
link: function (scope, element, attrs, ctrl) {
function init() {
element.calendar({
enableRangeSelection: true,
dataSource: scope.calendarData
});
}
// re-init when data is changed
scope.$watchCollection("calendarData", function(val) {
// according to the documentation, data can be updated by doing:
element.data("calendar").setDataSource(val);
});
init();
scope.$on("$destroy", function() {
// not sure if this is supported by the library,
// but is a best practice to prevent memory leaks
element.calendar("destroy");
});
}
}
}]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With