【问题标题】:Ember without Ember Data没有 Ember 数据的 Ember
【发布时间】:2014-08-16 00:42:37
【问题描述】:

Ember 数据仍然不是 1.0 版,因此我决定使用没有数据模型的 Ember。

我有自己的模型,它们是由路由模型函数创建的。

然而,维护前端对象和后端对象之间的状态是一场噩梦。 尤其是当一条路线使用另一条路线模型时。

  • 如何实现,我应该编写自己的商店和模型查找方法吗?
  • 我是否应该使用 Ember Data(即使它不是 1.0 版?)或者 Ember Data 1.0 上的 ETA?
  • 每次更改模型时都要编写代码来更新前端的模型?
  • 另一种方法?

我正在做的事情是最佳做法还是应该以不同的方式做? 我的直觉是,如果不使用 Ember Data,我应该编写自己的商店。我很想得到你们中的一些人的反馈。

模型示例:

App.Person = Ember.Object.extend(App.Serializable,Em.Copyable,{
  user_email : null //used in routing dynamic segements and as old email when making changes to email
  ,first_name: null
  , last_name: null
  , fullname : function () {
    return this.first_name + ' ' + this.last_name;
  }.property('first_name','last_name').cacheable()
};

App.Person.reopenClass({
  createRecord: function(data) {
    return App.Person.create({
      user_email : data.email
      , first_name: data.first_name
      , last_name : data.last_name
}});

我如何加载类模型的示例:

App.UsersRoute = App.AuthenticatedRoute.extend( {
  model : function () {
    return new Ember.RSVP.Promise(function(resolve, reject) {
      $.getJSON('/users').then(function(usersData) {
        var userObjects = [];
          usersData.forEach(function (data) {
            userObjects.pushObject(App.Person.createRecord(data));
          });
        resolve( userObjects);
        },function(error) {
          reject(error);
      });
    })
  },

子路由使用模型:

App.UsersAvailableRoute = App.AuthenticatedRoute.extend( {
     model : function () {
        return {
          allUsers :  Ember.ArrayController.create({
            content : this.modelFor('users').filter( function (user) {
                      return user.availablity === 100
                      }),

我如何在控制器中更新模型的示例:

App.UsersAvailableController = Ember.ArrayController.extend({
needs : ['users']
    ,applyPersonAssign : function (person,need,project) {
          need.set('allocated',person);
          var updateObject = Ember.copy(project,true);
          if (Ember.isEmpty(need.get('inProject'))) {
            updateObject.projectNeeds.pushObject(need);
          }

          return $.ajax({
            url: '/projects/' + updateObject.get('codename'),
            "type": "PUT",
            "dataType": "json",
            data: updateObject.serialize()
          })

【问题讨论】:

    标签: javascript model-view-controller ember.js ember-data


    【解决方案1】:

    您不一定需要重新创建 Ember 数据存储。 Ember 与 POJO 配合得很好,您还可以将 POJO 包装在 Ember 对象中,为您提供一些有趣的内置功能。

    也就是说,创建一个缓存结果的自定义适配器可能很方便。

    这是我创建支持缓存的适配器的示例。您可以在概念的基础上慢慢构建您需要的所有基本内容。

    App.FooAdapter = Ember.Object.extend({
      cache:{},
      find: function(id){
        var self = this,
            record;
        if(record = this.cache[id]){
          return Ember.RSVP.cast(record);
        }
        else
        {
          return new Ember.RSVP.Promise(function(resolve){
            resolve($.getJSON('http://www.foolandia.com/foooo/' + id));
          }).then(function(result){
            record = self.cache[id] = App.Foo.create(result);
            return record;
          });
        }
      }
    });
    

    在下面的示例中,我使用容器在我的所有路由/控制器上注册适配器,因此我可以轻松访问它。

    http://emberjs.jsbin.com/OxIDiVU/742/edit

    如果你总是希望它成为一个承诺:

    http://emberjs.jsbin.com/OxIDiVU/740/edit

    可重用性

    上面的例子可能会让你看起来需要做大量的工作,但不要忘记,Ember 是超级可重复使用的,利用它的魔力。

    App.MyRestAdapter = Em.Object.extend({
      type: undefined,
      find: function(id){
        $.getJSON('http://www.foolandia.com/' + this.get('type') + '/' + id
      }
    });
    
    App.FooAdapter = App.MyRestAdapter.extend({
      type: 'foo' // this would create calls to: http://www.foolandia.com/foo/1
    });
    
    App.BarAdapter = App.MyRestAdapter.extend({
      type: 'bar' // this would create calls to: http://www.foolandia.com/bar/1
    });
    

    这是 Ember 数据/Ember 模型的基本概念。他们试图创建大量默认值并内置酷炫,但有时这太过分了,特别是如果您只是使用数据而不进行 CRUD。

    例如:http://emberjs.jsbin.com/OxIDiVU/744/edit

    你也可以阅读这个(说同样的话):

    How do you create a custom adapter for ember.js?

    【讨论】:

    • 只是为了确认这行得通....我们非常广泛地使用这种方法,成功地拥有复杂的对象图和各种疯狂的网络服务:)
    • 或者您也可以按照本指南eviltrout.com/2013/03/23/ember-without-data.html
    • @fanta 谢谢,我看到了那篇文章,但它使用了 ES6 模块(我没有使用它,它使用了我不使用的 ember cli :)..
    • @kingpin2k 如果您已经找到了单个元素,您如何将其与 FindAll 一起使用?您是否进行迭代以确保不会两次加载同一个对象?
    • 我从另一段代码中复制了这个,我期望 RSVP.Promise 的一些功能(最后还是什么,我不记得了)。真的,我会为正确的工作选择正确的工具,Ember Data 让简单的事情变得简单,而让困难的事情变得非常困难(在目前的状态下)。如果您对编程感到自在,那么使用自己的编程并没有那么大的飞跃,并且可以根据您的需要轻松定制。对于 jquery 已经提供的出色 XHR 功能尤其如此(无论如何它都在您的应用程序中)。
    【解决方案2】:

    在我工作的地方,我们使用的是 Ember Data 和 Ember CLI,尽管它们相当不稳定。到目前为止,Ember Data 并没有给这里带来太多的痛苦和折磨。商店很容易理解,而且 Ember 上关于框架这方面的文档也相当不错。我遇到的一个问题与动态排序模型有关,当我修改它们的内容时,它们会根据我所做的更改重新洗牌,并且在路上的某个地方发生了一些非常奇怪的事情,不确定那是不是 Ember虽然是数据的错。

    简而言之,我们在使用 Ember Data 方面取得了一些成功,如果这就是您想要走的路,我们不能抱怨。

    【讨论】:

      【解决方案3】:

      如果您熟悉 Ruby,Rails 是一个很好的后端解决方案。

      ember 社区通过 ember-rails gem 支持 rails,这使您可以使用 rails 作为服务 JSON 的一种方式。

      开始

      • 将 gem 添加到您的应用程序 Gemfile:

        gem 'ember-rails' gem 'ember-source', '~> 1.9.0' # 或者你需要的版本

      • 运行bundle install

      • 接下来,生成应用结构:

        rails 生成 ember:bootstrap

      • 重新启动您的服务器(如果它正在运行)

      从头开始构建一个新项目

      Rails 支持从模板源 ruby​​ 文件构建项目的能力。

      要构建一个以 Ember 为中心的 Rails 项目,您只需在命令行中输入以下内容:

      rails new my_app -m http://emberjs.com/edge_template.rb
      

      安装最新版本的 ember 和 ember-data。应该指出的是, getting started guide 中的示例 已被设计为使用 ember 的已发布版本:

      rails generate ember:install
      

      然后你需要做的就是在你的控制器中渲染 json,像这样

      class ProjectsController < ApplicationController
          def index
              respond_to do |format|
                  format.json { render json: Project.all }
              end
          end
      
          def show
              respond_to do |format|
                  format.json { render json: Project.where(name: params[:name])}
              end
          end
      end
      

      确保更新您的序列化程序

      class ProjectSerializer < ApplicationSerializer
        attributes :id, :name, :description, :imgUrl, :deployUrl
      end 
      

      设置你的路线

      EmberRailsBlog.ProjectsRoute = Ember.Route.extend({
          model: function(){
              return this.store.find('project');
          }
      });
      

      最后是你的模型

      var attr = DS.attr;
      
      EmberRailsBlog.Project = DS.Model.extend({
          name: attr(),
          description: attr(),
          imgUrl: attr(),
          deployUrl: attr()
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-19
        相关资源
        最近更新 更多