没有 Ember 数据的 Ember

IT技术 javascript model-view-controller ember.js ember-data
2021-03-06 03:45:40

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()
          })
3个回答

您不一定需要重新创建 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

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

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 Data/Ember Model 的基本思想。他们试图创建大量默认值并内置冷静,但有时它是矫枉过正,特别是如果您只是消费数据而不是执行 CRUD。

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

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

如何为 ember.js 创建自定义适配器?

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

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

简而言之,我们已经发现使用 Ember Data 取得了一些成功,如果这是您想要的路线,请不要抱怨它。

如果您熟悉 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。需要注意的是,入门指南中的示例 已经设计为使用 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()
});