2013-03-04 2 views
0

Быстрое объяснение: Я работаю над базовым приложением, которое интегрировано с Fullcalendar JS. При создании или редактировании события вы можете щелкнуть по календарю, и появится всплывающее окно мода, запрашивающее информацию. Проблема в том, когда модальный всплывает, мне нужно использовать «this.model» для .get() информацию о текущем событии или .set() информацию о новом событии. Я получаю сообщение об ошибке:

Uncaught TypeError: Невозможно вызвать метод «получить» неопределенной
неперехваченным TypeError: Невозможно вызвать метод «набор» неопределенных"this.model" не работает над нажатием View. Backbone JS

Мой вопрос: Что такое правильный способ установить текущую модель щелчка?

Вот некоторые соответствующий код:

Модель & Коллекция:

var Event = Backbone.Model.extend({ 
    methodToURL: { 
     'create': addDayURL, 
     'update': addDayURL, 
     //'delete': '/user/remove' 
    }, 
    sync: function(method, model, options) { 
     options = options || {}; 
     options.url = model.methodToURL[method.toLowerCase()]; 

     Backbone.sync(method, model, options); 
    } 
}); 

var Events = Backbone.Collection.extend({ 
    model: Event, 
    url: allDaysURL 
}); 

Главная Просмотреть

var EventsView = Backbone.View.extend({ 
    events: { 
     'click #add_track' : "addTrack", 
     'click th.fc-widget-header:not(.fc-first)' : 'updateTrack', 
     'click .fc-button-next' : 'switchTracks', 
     'click .fc-button-prev' : 'switchTracks' 
    }, 
    initialize: function(){ 
     _.bindAll(this); 

     this.collection.on('reset', this.addAll); 
     this.collection.bind('add', this.addOne); 
     this.collection.bind('change', this.change);    
     this.collection.bind('destroy', this.destroy); 



     console.log(this.collection.toJSON()); 
     console.log(JSON.stringify(this.options.collection2.toJSON())) 

     this.trackCollection = JSON.stringify(this.options.collection2.toJSON()); 
     this.trackObject = jQuery.parseJSON(this.trackCollection); 

     this.eventView = new EventView(); 
     this.trackView = new TrackView();   
    }, 
    render: function() { 
     this.$el.fullCalendar({ 
      header: { 
       left: 'prev,next today', 
       center: 'title', 
       right: 'agendaDay', 

      }, 
      defaultView: 'resourceDay', 
      resources: this.trackObject, 
      droppable: true, 
      selectable: true, 
      selectHelper: true, 
      editable: true, 
      ignoreTimezone: false,     
      select: this.select, 
      eventClick: this.eventClick, 
      eventDrop: this.eventDropOrResize,   
      eventResize: this.eventDropOrResize, 
      drop: function(date, allDay, ev, ui, res) { // this function is called when something is dropped 

       // retrieve the dropped element's stored Event Object 
       var originalEventObject = $(this).data('eventObject'); 

       // we need to copy it, so that multiple events don't have a reference to the same object 
       var copiedEventObject = $.extend({}, originalEventObject); 

       // assign it the date that was reported 
       copiedEventObject.start = date; 
       copiedEventObject.allDay = allDay; 

       // dropped event of resource a to a cell belonging to resource b? 
       copiedEventObject.resourceId = res.id; 

       //get title of event 
       var eventTitle = copiedEventObject.title; 

       // render the event on the calendar 
       // the last `true` argument determines if the event "sticks" (http://arshaw.com/fullcalendar/docs/event_rendering/renderEvent/) 
       $('#calendar').fullCalendar('renderEvent', copiedEventObject, true); 

       // is the "remove after drop" checkbox checked? 
       if ($('#drop-remove')) { 
        // if so, remove the element from the "Draggable Events" list 
        $(this).remove(); 
       } 
       var event = new Event(); 
       event.set({"title": eventTitle, "start_at": copiedEventObject.start, "color": null, "allday":copiedEventObject.allDay, "conference_id": conferenceID, "session_type_id": 1, "resource_Id": res.id}); 
       events.create(event); 
      } 
     }); 

     //Goto first event day on initialize 
     var start_at = Date.parse(startDate); 
     var year = $.fullCalendar.formatDate(start_at, 'yyyy'); 
     var month = $.fullCalendar.formatDate(start_at, 'M'); 
     var day = $.fullCalendar.formatDate(start_at, 'dd'); 

     this.$el.fullCalendar('gotoDate', year , month, day) 
     this.$el.prepend('<button id="add_track" class="btn large-btn green-btn pull-right">Add Track</button>'); 
    }, 
    addAll: function() { 
     this.$el.fullCalendar('addEventSource', this.collection.toJSON()); 
    }, 
    addOne: function(event) { 
     this.$el.fullCalendar('renderEvent', event.toJSON()); 
    }, 
    addTrack: function() { 
     //get current day & format date 
     date = this.$el.fullCalendar('getDate'); 
     var formatDate = $.fullCalendar.formatDate(date, 'yyyy-MM-dd'); 

     //create new track 
     var newTrack = new Track; 
     newTrack.set({'name': 'Track 1', 'day_date': formatDate, 'conference_id': conferenceID, "session_type_id": 1}); 

     //save track to DB 
     this.options.collection2.create(newTrack); 
    }, 
    updateTrack: function(track) { 
     //var fcRes = this.$el.fullCalendar('clientEvents', event.get('id'))[0]; 
     //this.trackView.model = track.get('id'); 
     console.log(this.trackView.model) 
     this.trackView.render(); 
    }, 
    switchTracks: function(){ 
     //alert(this.$el.fullCalendar('getDate')) 
    }, 
    select: function(startDate, endDate, res) { 
     this.eventView.collection = this.collection; 
     this.eventView.model = new Event({start_at: startDate, end_at: endDate}); 
     this.eventView.render();    
    }, 
    eventClick: function(fcEvent) { 
     this.eventView.model = this.collection.get(fcEvent.id); 
     this.eventView.render(); 
    }, 
    change: function(event) { 
     // Look up the underlying event in the calendar and update its details from the model 
     var fcEvent = this.$el.fullCalendar('clientEvents', event.get('id'))[0]; 
     console.log(fcEvent); 
     fcEvent.title = event.get('title'); 
     fcEvent.color = event.get('color'); 
     this.$el.fullCalendar('updateEvent', fcEvent);   
    }, 
    eventDropOrResize: function(fcEvent) { 
     alert(fcEvent.id) 
     // Lookup the model that has the ID of the event and update its attributes 
     this.collection.get(fcEvent.id).save({start: fcEvent.start, end: fcEvent.end});    
    }, 
    destroy: function(event) { 
     this.$el.fullCalendar('removeEvents', event.id);   
    }   
}); 

Event Popup Модальные Просмотр

var EventView = Backbone.View.extend({ 
    el: $('#eventDialog'), 
    initialize: function() { 
     _.bindAll(this);   
    }, 
    render: function() { 
     var buttons = {'Ok': this.save}; 
     if (!this.model.isNew()) { 
      _.extend(buttons, {'Delete': this.destroy}); 
     } 
     _.extend(buttons, {'Cancel': this.close});    

     this.$el.dialog({ 
      modal: true, 
      title: (this.model.isNew() ? 'New' : 'Edit') + ' Event', 
      buttons: buttons, 
      open: this.open 
     }); 
     return this; 
    },   
    open: function() { 
     this.$('#title').val(this.model.get('title')); 
     this.$('#color').val(this.model.get('color'));    
    },   
    save: function(startDate, endDate, res) { 
     //copiedEventObject.resourceId = res.id; 
     this.model.set({'title': this.$('#title').val(), 'color': this.$('#color').val(), 'conference_id': conferenceID, "session_type_id": 1, 'track_id': 1, /*'resourceId': res.id*/}); 
     if (this.model.isNew()) { 
      this.collection.create(this.model, {success: this.close, wait: true}); 
     } else { 
      this.model.save({}, {success: this.close}); 
     } 
    }, 
    close: function() { 
     this.$el.dialog('close'); 
    }, 
    destroy: function() { 
     this.model.destroy({success: this.close}); 
    }   
}); 
+0

Не могли бы вы предоставить рабочий пример JSFiddle с этим примером? –

ответ

1

Похоже, у вашего вида календаря нет модели, связанной с ней. Вам нужно будет передать модель в представление календаря при ее создании. Когда вы вызываете this.eventView = new EventView();, вы не предоставляете ему ссылку на свою базовую модель в своем основном представлении.

+0

Я попытался создать JSfiddle, но без файлов serveride он просто дал ошибки ... Я также пробовал ваше предложение, но я все равно получаю ту же ошибку. Я думаю, что это может быть связано с этой строкой 'this.eventView.model = this.collection.get (fcEvent.id);' b/c, где устанавливается новая модель eventView. Но я не могу определить, почему это не определено. Кроме того, я работал над этим уроком, http://blog.shinetech.com/2011/08/05/building-a-shared-calendar-with-backbone-js-and-fullcalendar-a-step-by -step-tutorial /, который может содержать более краткий/чистый код. Спасибо :) –

+0

еще лучше, но это не заполняется b/c этой строки 'var fcEvent = this. $ El.fullCalendar ('clientEvents', event.get ('id')) [0];' на изменить событие. Любая идея, почему это было бы undefined ?? –

+0

Итак, просто чтобы уточнить, ваш основной вид - это вид календаря с использованием Fullcalendar.js, и модальный вид открывается, когда вы нажимаете на одно из событий из полного представления календаря, и эта часть работает, эта проблема заключается в том, что вы хотите, чтобы модель случая, чтобы быть моделью модального, который открыт, является правильным? –

Смежные вопросы