2

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-model のある種の時計ですか? もしそうなら、どうすれば選択した日付を設定できますか?

更新: 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);

      }
4

3 に答える 3

3

これはカレンダーのバグです。あなたは StackOverflow でそれについて何かを言う最初の人です。称賛。

これを修正するには、いくつかの方法があります。github https://github.com/angular-ui/angular-ui/pull/520で、ウォッチが起動されるたびにディレクティブが再作成される方法を廃止することが提案されています。これにより、この動作が停止します。この方法を本番環境で機能させることができれば、それが最善の解決策になると思います。

それまでは、view.start フィールドから作成された日付オブジェクトから現在の月を取得することで解決します。この月は、カレンダーのレンダリングに使用されるオプションに追加する必要があります。

これは、カレンダー ディレクティブ内で新しい更新関数がどのように見えるかのスニペットです。

/* 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 サーバーで適切にテストされていませんが、現在実稼働環境で使用しているため、正常に動作します。

于 2013-03-29T14:28:25.217 に答える
0

Angular-UI ソースを変更せずに問題を解決する別の方法は、次のようにカレンダーを宣言することです。

<div ui-calendar="{viewDisplay:viewDisplayHandler,month:monthVal,year:yearVal}" ng-model="eventsArr"></div>

そして、カレンダー全体の再作成後にカレンダーの日付を設定するために、適切な値を設定するviewDisplayHandler関数をスコープ内に持つには:monthValyearVal

$scope.viewDisplayHandler = function(view) {
    var viewStart = view.start;
    $scope.yearVal = viewStart.getFullYear();
    $scope.monthVal = viewStart.getMonth();
}

これは、GitHubでプルリクエストを発行する前に解決した方法です。それは私が推測する最適な方法ではありませんが、私はしばらくの間本番環境で使用しており、問題ないようで、Angular-UI のコードを変更する必要はありません。

于 2013-03-30T10:07:12.343 に答える
0

ディレクティブで FullCalendar をラップする AngularUI を使用すると、$scope.calendar を介してカレンダー オブジェクトにアクセスできます。「AngularJS の方法」は、コントローラーでの直接 DOM 操作を回避することです。

あなたの特定のケースでは、代わりにこれを書きます:

$scope.calendar.fullCalendar('gotoDate', 2012, 11);

AngularUI には、どちらかの長さが変化するたびに update 関数を呼び出す eventSource と event の監視があります。ここでソースを表示できます:

https://github.com/angular-ui/angular-ui/blob/master/modules/directives/calendar/calendar.js

イベント モデルが変更されるたびに、$scope.calendar のカレンダー オブジェクトが新しいイベント セットで再作成されることがわかります。これが、日付の変更が行われない理由です。イベントが追加され、更新がトリガーされ、日付の変更が行われ、カレンダー全体が変更され、日付の変更が失われます。

AngularUI のコードを変更せずに 2 つの (最善ではない) ポップアップが表示されます。

  1. AngularJS の $timeout サービスを使用して、イベントが読み込まれた後、設定された時間待機し、カレンダーの更新が終了してから、日付の変更を呼び出すことができます。

  2. カレンダー オブジェクトが変更されるたびに日付の変更をトリガーするスコープに $watch を追加できます。

    http://plnkr.co/edit/Ww08VX?p=preview

上記の例を作成しました。test() メソッドでは、promise (2013 年 3 月に追加される予定) を介していくつかの偽のデータをイベントにロードし、日付を 2012 年 12 月に変更しています。 (ディレクティブで更新がトリガーされます) date コマンドを再送信します。2012 年 12 月に移動しても、新しいイベントが表示されることはありませんが、2013 年 3 月に戻ると、そこにあるはずです。私は時計を別のものに貼り付けました。次に、返された値を使用して日付を動的に設定すると仮定します。

于 2013-03-29T02:11:34.883 に答える