如何将数组对象绑定到FullCalendar事件?

时间:2019-05-09 19:40:04

标签: javascript vue.js fullcalendar fullcalendar-4

Vue.component('full-calendar', {
    template: '<div ref="calendar"></div>',
    props: {
      tasks: {
        type: Array, 
        required: true
      },

      newtask: Object
    },
    watch: {
        tasks: function (task) { 
            
            // this.tasks.push(task);
            // this.cal.calendar.addEvent({
            //     title: task.title,
            //     start: task.start,
            //     end: task.end
            //  });
            

             $("#addTaskModal").modal('hide');

    }},
    data () {
      return {
        cal: null
      }
    },

    methods: {

        init:function(){

            var self = this;
        self.cal = $(self.$refs.calendar);
    
      var args = {
        firstDay: 1,
        lang: 'en',
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'addTaskButton / dayGridMonth,timeGridWeek,listMonth'
        },
        height: "auto",
        allDaySlot: false,
        slotEventOverlap: false,
        timeFormat: 'HH:mm',
        plugins: ["interaction", "dayGrid"],
        eventLimit: true,
        events: this.tasks,
        
        dateClick: function(date)
          {
              self.$emit('date_clicked', date);
              console.log('date clicked');
              console.log(this);
        },
  
        eventClick: function(event)
          {
                  self.$emit('event_clicked', event);
          },

          customButtons: {
            addTaskButton: {
                text: 'Add Task',
                click: function() {
                    $("#addTaskModal").modal('show');
                }
            }
        }
      }
      
      if (self.editable)
      {
        args.editable = true;
        args.eventResize = function(event)
        {
          self.$emit('event::resized', event);
        }
        
        args.eventDrop = function(event)
        {
          self.$emit('event::dropped', event);
        }
      }
      
      if (self.droppable)
      {
        args.droppable = true;
        args.eventReceive = function(event)
        {
          self.$emit('event::received', event);
        }
      }
      
      self.cal.calendar = new FullCalendar.Calendar(self.$el,args);

      self.cal.calendar.render();
        }


    },
    mounted () {

        this.init(); 
    }
    
  })
  
  let vm = new Vue({
    el: '#app',

    data () {
       return {
          tasks: [
             {
                title: 'Event1',
                start: '2019-05-10 12:30:00',
                end: '2019-05-10 16:30:00'
             },
             {
                title: 'Event2',
                start: '2019-05-07 17:30:00',
                end: '2019-05-07 21:30:00'
             }
          ],
          editable: false,
          selectedDate : moment().format('DD-MM-YYYY'),
          task: {
            title:null,
            start: '2019-05-07 17:30:00',
            end: '2019-05-07 21:30:00'
          },
          newtask: {}
       }
    },
    

    methods: {

        addTask: function(event){
            
            var d = moment().format('YYYY-MM-DD');

            var sel = new Date(this.selectedDate.replace( /(\d{2})-(\d{2})-(\d{4})/, "$2/$1/$3"));

            //console.log();
            
            var date = new Date(moment(sel).format('YYYY-MM-DD')+ 'T00:00:00'); // will be in local time
            
            this.tasks.push({
                title: this.task.title,
                start: date,
                end: date
              });

              this.$nextTick(function () {
                // DOM is now updated
                // `this` is bound to the current instance
                //this.doSomethingElse()
              })
        },

        dateClicked: function(date) {
            this.selectedDate = moment(date.date).format('DD-MM-YYYY');
          },

        eventClicked: function(event) {
            this.selectedDate = moment(event.event.start).format('DD-MM-YYYY');
          },

          showObject: function() {

            console.log(this.tasks);
          }
    
    
    }
  })
<link href="https://fullcalendar.io/releases/core/4.1.0/main.min.css" rel="stylesheet"/>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>



<script src="https://fullcalendar.io/releases/core/4.1.0/main.min.js"></script>
<script src="https://fullcalendar.io/releases/daygrid/4.1.0/main.min.js"></script>
<script src="https://fullcalendar.io/releases/interaction/4.1.0/main.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>



<div class="container mt-5" id="app">
    <div>

        <div class="row">
            <div class="col-md-8">
                <full-calendar 
                v-bind:tasks="tasks" 
                v-on:date_clicked="dateClicked"
                v-on:event_clicked="eventClicked"
                :newtask="newtask"
                ></full-calendar>
            </div>
            
        <div class="col-md-4">
          
            <div class="pb-3">
                    <span id="CurrentDate" class="" style="cursor: pointer;">{{selectedDate}}</span>
                    <span class="badge badge-primary">{{tasks.length}}</span>
                    <button @click="showObject">show object</button>
            </div>

          <table class="table table-condensed">
            <tbody v-for="task in tasks">
              <tr>
                <td>
                  <input
                    type="checkbox"
                  />
                </td>
                <td>{{task.title}}</td>
                <td></td>
              </tr>
            </tbody>
            <tbody>
              <tr v-if="tasks.length==0">
                <td colspan="3" class="text-center">No tasks to display</td>
              </tr>
            </tbody>
          </table>



 
        </div>
        </div>
    </div>

    <div class="modal fade" id="addTaskModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
        <div class="modal-dialog" role="document">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="exampleModalLabel">Add a task</h5>
              <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
            <div class="modal-body">
                    <div class="form-group">
                            <input type="text" id="NewTaskTitle" placeholder="Enter task name" class="form-control" v-model="task.title" />
                    </div>
            </div>
            <div class="modal-footer">
              <button class="btn btn-success btn-sm" @click="addTask">Add</button>
              <button data-bind="click: CancelAddNewTask" class="btn btn-seconday btn-sm" data-dismiss="modal">Cancel</button>
            </div>
          </div>
        </div>
    </div>
</div>

大家好,

我试图将对象“任务”与完整的日历事件绑定在一起,但是它不起作用。

请参见上面提供的示例。请整页查看

添加任务时,我希望它可以添加到任务对象中,并且当然可以绑定到完整日历中的事件。

基本上,我想将task数组绑定到完整的日历事件对象,因此,例如,如果我删除了一个项目,也应该从完整的日历事件中删除

如果我做错了,请告诉我。谢谢一堆

[1]:

2 个答案:

答案 0 :(得分:1)

当新任务从“父”(新Vue)发送给“子”(全日历)时,它应该像更新FullCalendar一样简单。

在您的全日历组件中,您应该能够调用render()方法,根据FullCalendar文档,该方法将重新渲染日历(如果已经存在)。在您的体系结构中,就像调用init()方法一样简单。我还将紧密的模态逻辑移到了适当的位置。这可能会使用户进行更多的重构,但这应该会让您感到困惑。希望对您有所帮助。

watch: {
  tasks: function (task) { 
    this.cal.calendar.render();
  }
}

https://fullcalendar.io/docs/render

Vue.component('full-calendar', {
    template: '<div ref="calendar"></div>',
    props: {
      tasks: {
        type: Array, 
        required: true
      },

      newtask: Object
    },
    watch: {
      tasks: function (task) { 
            this.init()
      }
    },
    data () {
      return {
        cal: null
      }
    },

    methods: {

        init:function(){

            var self = this;
        self.cal = $(self.$refs.calendar);
    
      var args = {
        firstDay: 1,
        lang: 'en',
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'addTaskButton / dayGridMonth,timeGridWeek,listMonth'
        },
        height: "auto",
        allDaySlot: false,
        slotEventOverlap: false,
        timeFormat: 'HH:mm',
        plugins: ["interaction", "dayGrid"],
        eventLimit: true,
        events: this.tasks,
        
        dateClick: function(date)
          {
              self.$emit('date_clicked', date);
              console.log('date clicked');
              console.log(this);
        },
  
        eventClick: function(event)
          {
                  self.$emit('event_clicked', event);
          },

          customButtons: {
            addTaskButton: {
                text: 'Add Task',
                click: function() {
                    $("#addTaskModal").modal('show');
                }
            }
        }
      }
      
      if (self.editable)
      {
        args.editable = true;
        args.eventResize = function(event)
        {
          self.$emit('event::resized', event);
        }
        
        args.eventDrop = function(event)
        {
          self.$emit('event::dropped', event);
        }
      }
      
      if (self.droppable)
      {
        args.droppable = true;
        args.eventReceive = function(event)
        {
          self.$emit('event::received', event);
        }
      }
      
      self.cal.calendar = new FullCalendar.Calendar(self.$el,args);

      self.cal.calendar.render();
        }


    },
    mounted () {

        this.init(); 
    }
    
  })
  
  let vm = new Vue({
    el: '#app',

    data () {
       return {
          tasks: [
             {
                title: 'Event1',
                start: '2019-05-10 12:30:00',
                end: '2019-05-10 16:30:00'
             },
             {
                title: 'Event2',
                start: '2019-05-07 17:30:00',
                end: '2019-05-07 21:30:00'
             }
          ],
          editable: false,
          selectedDate : moment().format('DD-MM-YYYY'),
          task: {
            title:null,
            start: '2019-05-07 17:30:00',
            end: '2019-05-07 21:30:00'
          },
          newtask: {}
       }
    },
    

    methods: {

        addTask: function(event){
            
            var d = moment().format('YYYY-MM-DD');

            var sel = new Date(this.selectedDate.replace( /(\d{2})-(\d{2})-(\d{4})/, "$2/$1/$3"));

            //console.log();
            
            var date = new Date(moment(sel).format('YYYY-MM-DD')+ 'T00:00:00'); // will be in local time
            
            this.tasks.push({
                title: this.task.title,
                start: date,
                end: date
              });
              
              $("#addTaskModal").modal('hide');

              this.$nextTick(function () {
                // DOM is now updated
                // `this` is bound to the current instance
                //this.doSomethingElse()
              })
        },

        dateClicked: function(date) {
            this.selectedDate = moment(date.date).format('DD-MM-YYYY');
          },

        eventClicked: function(event) {
            this.selectedDate = moment(event.event.start).format('DD-MM-YYYY');
          },

          showObject: function() {

            console.log(this.tasks);
          }
    
    
    }
  })
<link href="https://fullcalendar.io/releases/core/4.1.0/main.min.css" rel="stylesheet"/>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>



<script src="https://fullcalendar.io/releases/core/4.1.0/main.min.js"></script>
<script src="https://fullcalendar.io/releases/daygrid/4.1.0/main.min.js"></script>
<script src="https://fullcalendar.io/releases/interaction/4.1.0/main.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>



<div class="container mt-5" id="app">
    <div>

        <div class="row">
            <div class="col-md-8">
                <full-calendar 
                v-bind:tasks="tasks" 
                v-on:date_clicked="dateClicked"
                v-on:event_clicked="eventClicked"
                :newtask="newtask"
                ></full-calendar>
            </div>
            
        <div class="col-md-4">
          
            <div class="pb-3">
                    <span id="CurrentDate" class="" style="cursor: pointer;">{{selectedDate}}</span>
                    <span class="badge badge-primary">{{tasks.length}}</span>
                    <button @click="showObject">show object</button>
            </div>

          <table class="table table-condensed">
            <tbody v-for="task in tasks">
              <tr>
                <td>
                  <input
                    type="checkbox"
                  />
                </td>
                <td>{{task.title}}</td>
                <td></td>
              </tr>
            </tbody>
            <tbody>
              <tr v-if="tasks.length==0">
                <td colspan="3" class="text-center">No tasks to display</td>
              </tr>
            </tbody>
          </table>



 
        </div>
        </div>
    </div>

    <div class="modal fade" id="addTaskModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
        <div class="modal-dialog" role="document">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="exampleModalLabel">Add a task</h5>
              <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
            <div class="modal-body">
                    <div class="form-group">
                            <input type="text" id="NewTaskTitle" placeholder="Enter task name" class="form-control" v-model="task.title" />
                    </div>
            </div>
            <div class="modal-footer">
              <button class="btn btn-success btn-sm" @click="addTask">Add</button>
              <button data-bind="click: CancelAddNewTask" class="btn btn-seconday btn-sm" data-dismiss="modal">Cancel</button>
            </div>
          </div>
        </div>
    </div>
</div>

答案 1 :(得分:0)

watch: {
  tasks: function (tasks) {
    this.calendarOptions.events = tasks;
    let calendarApi = this.$refs.fullcalendar.getApi();
    calendarApi.render();
  },
},

... ...

<FullCalendar
  ref="fullcalendar"
  :options="calendarOptions"
/>