如果$ scope模型更改但仍保持相同的长度,为什么Angular-UI日历​​不会更新?

时间:2013-01-30 09:44:22

标签: javascript angularjs fullcalendar angular-ui

我正在AngularUI中编写一个事件日历,并进行了一些过滤。

<div
    id="calendar"
    ui-calendar="{ height: 450, editable: false, defaultView: 'month' }" 
    class="span9 pull-right calendar"
    ng-model="events"
</div>

当更改过滤器下拉列表时,会触发一个函数,该函数应执行一些voodoo并更新$ scope.events。

(缩短)

// Clear $scope.events
$scope.events = [];

// Initialise new events
var new_events = all_events;

if($scope.events_filter.type != 'all') {

    // Do filter
    new_events = json_service.filter(
        new_events,
        'type',
        $scope.events_filter.type
    );
}

// Update $scope.events
$scope.events = new_events;

让我们从6个事件开始。如果有两个'类型',每个有3个事件,并且让我们调用一个类型A和一个类型B,则可以从全部更改为A,并且将正确显示三个事件。如果您改回“全部”,则会有6个可见。

如果从A更改为B,则日历不会更新,但检查$ scope.events是否显示数据已更改。

过滤有效,$ scope.events正在更新。

问题似乎是如果$ scope.events长度没有改变 - 它看起来不适合重绘日历。

2 个答案:

答案 0 :(得分:3)

你是对的。如果事件数组的长度未更改,则日历将不会更新。这是因为angular不会检测整个数组对象的变化(不抛出摘要错误),而是需要观察更集中的变量集或者观察返回一个事件源才能正常工作的函数。

两次编辑解决了这个具体问题。将getOptions()添加到watch方法值,并观察第一个事件源或观察所有事件源并将equalsTracker添加到指令的属性。

以下是日历的链接,该日历可从筛选服务中切换出2个事件数组。 (但这并不能解决您的问题)http://plnkr.co/edit/VbYDNK?p=preview

日历现在正在eventSources中查看第一个事件数组。因此,现在您想要在范围上使用angular控制的任何事件都可以添加到第一个数组中,然后如果您需要提取任何源,您可以在任何给定时间或您选择的任何其他方法调用fullcalendar的addSource方法。

这是一个更开放的日历,创造了许多攻角。

这是指向正在观看第一个阵列本身而不是其长度的日历的链接。这也有效,所以也许我们应该选择这个。 (这解决了你的问题)http://plnkr.co/edit/AU6KNZ?p=preview

我已经读过,它可能导致性能问题,无法观看大型数组。

编辑:       我已经回到绘图板,找到了解决所有这些问题的方法。现在我们不再需要在事件源中观察第一个数组,而是只能观察跟踪器变量。 tracker变量将监视eventSources中所有事件的长度加上eventSources本身的长度。这将允许在eventSources中监视任何数组,并仍然允许角度来做它的魔力。

由于此特定用例,equalsTracker属性已添加到日历中。此equalsTracker属性必须是一个数字,并且应在运行过滤器服务时更新,并且生成的事件数组与正在过滤的当前scope.events数组具有相同的长度。

答案 1 :(得分:0)

我找到了解决方案!在joshkurz的帮助下,我意识到它只是检查长度变化。

简单的解决方案: -

在过滤$ scope.events的检查长度之前。

过滤$ scope.events的检查长度。

var length = $scope.events.length;
$scope.events = [];
var new_events = all_events;

... filter new_events a little bit ...

$scope.events = new_events;

if($scope.events.length == length) {
    $scope.events.push({});
}

长度不再相同;)

谢谢乔什:)