我使用带有Angular UI的FullCalendar设置日历。它工作正常,我可以很好地切换事件类别,但每次更新eventSource时,日历视图都设置为当前日期。
我已经尝试使用gotoDate
方法,我可以看到它有效(它也可以在控制台上运行),但几乎是在日历恢复到当前日期之后。由于我是AngularJS的新手,我可能会将gotoDate
置于错误的位置。但我无能为力地把它放在其他地方。
我正在使用一个返回一堆事件对象的服务,并将它们推送到eventSources
,即日历元素的ng-model。没有什么特别的,在我的控制器中:
$scope.eventSources = [];
var promise = UserCalendarEvents.get(groupName);
promise.then(
function(events) {
$scope.eventSources.push(events);
$('#events-calendar').fullCalendar('gotoDate', 2012, 11);
},
function(reason) {
console.log('Error: ' + reason);
}
);
在这种情况下,将获取事件并填充$scope.eventSources
。然后将日历视图设置为2012年12月,之后几乎立即将视图切换到当前日期。它是某种类型的ng模型手表重新渲染全日历,如果是这样,我如何设置选择日期?
更新:我结束了使用joshkurz修复程序,但是在一个修改版本中尊重所选视图,即如果用户选择了basicWeek并更改了源数据,则视图不应更改为例如月份视图。这就是我的用户所需要的。
function update() {
scope.calendar = elm.html('');
var view = scope.calendar.fullCalendar('getView');
var m;
var xtraOptions = {};
//calendar object exposed on scope
if(view){
var viewDate = new Date(view.start);
if(m !== 'Invalid Date'){
y = viewDate.getFullYear();
m = viewDate.getMonth();
d = viewDate.getDate();
if(!isNaN(y) && !isNaN(m) && !isNaN(d)){
xtraOptions = {
year: y,
month: m,
date: d
};
}
}
view = view.name; //setting the default view to be whatever the current view is. This can be overwritten.
}
/* If the calendar has options added then render them */
var expression,
options = { defaultView : view, eventSources: sources };
if (attrs.uiCalendar) {
expression = scope.$eval(attrs.uiCalendar);
// Override defaultView if is set in ui-calendar attribute - OK?
if (expression.defaultView) {
expression.defaultView = view;
}
} else {
expression = {};
}
angular.extend(options, uiConfig.uiCalendar, expression, xtraOptions);
scope.calendar.fullCalendar(options);
}
答案 0 :(得分:3)
这是日历的错误。你是第一个在StackOverflow上对它说些什么的人。奖励。
有几种方法可以解决这个问题。它是在github https://github.com/angular-ui/angular-ui/pull/520上提出的,我们废除了指令在触发监视时重新创建的方式,这将阻止这种行为。我相信如果我们能够将这种方法用于生产,那么它将是最好的解决方案。
在此之前,修复方法是从view.start字段创建的日期对象中获取当前月份。应将此月份添加到用于呈现日历的选项中。
以下是新更新函数在calendar指令内部应该是什么样的片段。
/* update the calendar with the correct options */
function update() {
scope.calendar = elm.html('');
var view = scope.calendar.fullCalendar('getView');
var m;
var xtraOptions = {};
//calendar object exposed on scope
if(view){
var d = new Date(view.start);
m = new Date(view.start);
if(m !== 'Invalid Date'){
m = m.getMonth();
if(!isNaN(m)){
xtraOptions = {
month: m
};
}
}
view = view.name; //setting the default view to be whatever the current view is. This can be overwritten.
}
// console.log(m)
/* If the calendar has options added then render them */
var expression,
options = {
defaultView : view,
eventSources: sources
};
if (attrs.exCalendar) {
expression = scope.$eval(attrs.exCalendar);
} else {
expression = {};
}
angular.extend(options, uiConfig.exCalendar, expression, xtraOptions);
scope.calendar.fullCalendar(options);
}
这在angular-ui CI服务器上没有经过适当的测试,但它正常,因为我目前在生产中使用它。
答案 1 :(得分:1)
在不更改Angular-UI源的情况下解决问题的另一种方法是声明日历,如下所示:
<div ui-calendar="{viewDisplay:viewDisplayHandler,month:monthVal,year:yearVal}" ng-model="eventsArr"></div>
要在范围内设置viewDisplayHandler
函数,将monthVal
和yearVal
设置为适当的值,以便在整个日历重新设置之后在日历上设置日期:< / p>
$scope.viewDisplayHandler = function(view) {
var viewStart = view.start;
$scope.yearVal = viewStart.getFullYear();
$scope.monthVal = viewStart.getMonth();
}
这是我在GitHub上发出pull请求之前解决的问题。它不是我想的最佳方法,但我已经在生产中使用了一段时间,它似乎没问题,也不需要更改Angular-UI的代码。
答案 2 :(得分:0)
使用AngularUI将FullCalendar包装在指令中,可以通过$ scope.calendar访问日历对象。 “AngularJS Way”是为了避免控制器中的直接DOM操作。
在你的特定情况下,你会写这个:
$scope.calendar.fullCalendar('gotoDate', 2012, 11);
AngularUI确实监视eventSource和事件,每次更改时都会调用更新函数。您可以在此处查看来源:
https://github.com/angular-ui/angular-ui/blob/master/modules/directives/calendar/calendar.js
每次事件模型更改时,您都可以看到$ scope.calendar中的日历对象使用一组新事件进行重新创建。这就是为什么您的日期更改未通过 - 正在添加事件,触发更新,日期更改进入,整个日历更改以及日期更改丢失。
在不改变AngularUI代码的情况下,两个(不是最好的)东西出现在我面前:
您可以使用AngularJS的$ timeout服务并等待一组 加载事件后的时间,日历已完成更新, 然后调用你的日期更改。
您可以在触发日期更改的范围上添加$ watch 每次日历对象发生变化时:
我在上面创建了这个例子。在test()方法中,我只是通过一个承诺(它们将在2013年3月添加)将一些虚假数据加载到事件中,然后将日期更改为2012年12月。我正在观看$ scope.calendar并且每次更改(在指令中触发更新)我重新发送date命令。你应该被送到2012年12月,甚至没有看到新活动进入,但如果你回到2013年3月,他们应该在那里。我把手表放在另一个手表上。然后假设你将使用一些值来动态设置日期。