如何在Ember 1.0.0-RC3中将emberjs对象转换为JSON

时间:2013-05-30 00:22:45

标签: ember.js ember-data

我需要将JSON传递给jquery-fullcalendar,虽然我可以将使用url作为获取JSON的源,但我更愿意将已经加载到ember-data存储中的数据转换为JSON并将其传递给fullcalendar,因此,在日历或余烬上进行的任何更改都将始终保持同步。

当我使用ember对象作为模型并在内存中创建数据时,它的工作原理如下所示: here 。但是当我通过ember-data rest-adapter加载数据并尝试使用相同的代码将其转换为JSON时,它就失败了。

以下是 failing JSfiddle

当使用ember对象创建数据时,我可以通过手动创建json来使其工作,如下所示 here 并粘贴:

当我使用Ember对象作为模型时,它会生成一个由fullcalendar接受的有效JSON。但是,如果我将其更改为使用ember-data模型,即 App.Event = DS.Model.extend 并相应地更改属性以使用 DS.attr ,控制器仍然是相同的,它将无法生成fullcalendar接受的有效json。

App.Event = Em.Object.extend( {
  title: null,
  start: null,
  allDay: null,

  asJSON: function() {
    return {
        title: this.get('title'),
        start: this.get('start'),
        allDay: this.get('allDay')
    };
  }.property('title', 'start', 'allDay')    

});

使用ember对象时工作的控制器,但使用ember-data

时不工作
  App.EventsController = Ember.ArrayController.extend({
     content: [
       App.Event.create({
         title: 'event1',
        start: '2013-06-06'
       })
    ],

    contentAsJSON: function() {
        return this.get('content').map(function(event) {
          return event.get('asJSON');
        });
    }.property('content.[]')
 });

这是我将生成的JSON从上面的模型和控制器传递给jquery-fullcalendar的方法。这里json被fullcalendar和日历上显示的事件识别。您可以看到 here

  App.CalendarView = Em.View.extend({
    templateName: 'calendar',

    didInsertElement: function() {
    this._super();

    var controller = this.get('controller');
    var calendarJSON = controller.eventJSON();
    console.log(calendarJSON);

    this.$().fullCalendar({
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'month,agendaWeek,agendaDay'
        } , 


        editable: true,
       events: calendarJSON
    });
   }
});

如果我将ember-object转换为ember-data的DS模型,我该如何生成json。到目前为止,只是为ember-data换掉ember对象是行不通的。

更新

根据@Gevious的回答 jsfiddle

通过@Gevious调整工作代码,因此它只显示一个日历而不是多个日历: jsfiddle

最终工作答案

我将didInsertElement和jquery fullcalendar的初始化从控制器移回到视图中,一切仍然按照我想要的方式工作。

将Ember-data作为数据存储区: http://jsfiddle.net/C4SD7/5/ http://jsfiddle.net/C4SD7/3/ 。使用Ember-Model作为数据存储: http://jsfiddle.net/C4SD7/6/ 除了fullcalendar之外,这里还有一个链接,用于将 datepicker与emberjs http://jsfiddle.net/jsjyw/3/一起使用。将Momentjs与日历一起使用: http://jsfiddle.net/M8XLF/7/并更改fullcalendar的颜色:http://jsfiddle.net/A56LN/43/。事件使用ember-model作为数据存储区加载约会:http://jsfiddle.net/duHfN/15/。使用ember-data作为数据存储的相同代码:http://jsfiddle.net/duHfN/14/

非常感谢。

1 个答案:

答案 0 :(得分:2)

我在当地复制了你的非工作小提琴。在控制台中,我收到以下错误消息:

Uncaught Error: assertion failed: an Ember.CollectionView's content must implement Ember.Array.   You passed <(generated appointments controller):ember306> ember-1.0.0-rc.3.js:52
Uncaught Error: assertion failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications. ember-1.0.0-rc.3.js:52

好好看看你的代码后,我建议你稍微改变一下。你尝试做事的方式并没有退出适合的余烬约定(恕我直言)。我建议您为约会和事件设置页面,如下所示。

App.Router.map(function() {
  this.route('appointments');
  this.route('events');
});

然后在约会路线中添加模型:

App.AppointmentsRoute = Em.Route.extend({
  model: function() return App.Event.model();
});

通过这种方式,您知道您只处理约会堆栈(路由/控制器/模型/视图)并可以继续调试。您现在已经开始设置项目的方式,将不同的视图投入到您的应用程序中会有太大的错误。

一旦您完成约会,您就可以随时使用所拥有的内容,并将不同的视图呈现为应用程序内的部分内容。通过这种方式,您将清理代码并使用ember约定,同时仍将所有内容保存在一个页面上。

<强>更新

我已经提出fiddle你可以看一下我的意思。这些活动位于/ calendar和/ calendar下的/ events下。我没有小提琴可以很好地工作,但如果你把它复制到你的机器上,你会发现浏览事件可以为你提供事件,浏览到日历可以为你提供填充事件的日历。

除此之外,我注意到你没有将余烬数据作为外部js的一部分。这可能就是没有可用的CDN(我没有检查过),但一定要在代码中包含ember-data.js库。模型和灯具取决于该库。您可以下载最新版本from here

更新2 Here is a new fiddle。它会重定向到事件视图,该视图会显示包含所有事件的事件和日历。事件更新后,日历也应更新。我不得不将渲染移动到控制器中以实现这一目标