ember.js - 用于创建新模型的正确控制器/视图模式是什么

时间:2012-04-20 08:05:52

标签: javascript ember.js

我有一个应用程序,目前包含同一模型的对象视图。它们从服务器检索,循环并使用add方法

添加到列表控制器
<script>
App.Controllers.List = Em.ArrayProxy.create({
  content: Ember.A([]),
  add: function(obj){
    this.pushObject(obj);
  }
});
</script>

我现在正处理一个用户创建新对象的部分,该对象在通过验证后将被添加到列表中并发送到服务器。

我找不到关于通过输入表单创建新对象的最佳模式的任何示例。我可以看到一些选项,并且半实现了一些,但没有什么感觉正确。

  • 使用适当的表单元素和使用.get()
  • 从表单元素检索的各种属性实例化模型的方法创建视图
  • 在视图的内容中创建模型,并将表单元素绑定到该模型。在视图中包含一个方法,以添加到控制器阵列/保存到服务器
  • 创建模型,将其添加到控制器阵列并打开它进行编辑

我可以解决我想要的功能,但我更愿意确保我了解最佳做法。

我目前有这样的东西(这是我名单上的第二个子弹)

<script>
App.Views.ItemCreate = Em.View.extend({
  content: App.Models.Item.create({}),
  templateName: 'create',
  createButton: function(){

    var itemObj = this.get('content');
    var item = {};
    item.title = this.get('content').get('title');

    $.ajax({
      type: 'POST',
      url: '/test/data.json',
      data: item,
      dataType: 'json',
      success: function(responseData, textStatus, jqXHR) {
        App.Controllers.List.add(itemObj);
      }
    });
  }
});
</script>

<script type="text/x-handlebars" data-template-name="create">
  {{view Em.TextField id="create-title" valueBinding="content.title"}}
  <a href="#" {{action "createButton" }}>Create</a>
</script>

任何帮助非常感谢

备注

我已经改变了pangratz的正确答案。虽然其他回复直接回答了我的问题,但我相信那些通过Google找到这个问题的人应该参考Pangratz提供的答案,因为它不仅是好的MVC,而且更多的是Ember-y:o)

2 个答案:

答案 0 :(得分:23)

与服务器通信绝对不应该在视图中完成。这是控制器的用途。为了进一步分离应用程序的不同部分,我甚至会考虑实现一个处理AJAX请求的DataSource。这种拆分使您的应用程序更易于测试,并且每个组件都可以重用。然后通过绑定实现视图,控制器和数据源的具体连接。

您案例的工作流程可能如下:

  • 该视图显示您的编辑表单,其中“值已绑定到控制器
  • 视图处理保存操作,告知控制器保存创建的对象
  • 控制器将保存委托给DataSource,然后最终启动AJAX请求
  • 保存对象时会通知控制器

您还应该查看ember-data哪个是客户端数据存储,并为您处理所有样板文件。另请查看The architecture of Ember.js apps - dataEmberJS: Good separation of concerns for Models, Stores, Controllers, Views in a rather complex application?


查看:

App.View.ItemCreate = Ember.View.extend({
  templateName: 'create',
  createObject: function(evt) {
    var object = this.get('content');
    var controller = this.get('controller');
    controller.createObject(object);
  }
});

控制器:

App.Controllers.List = Ember.ArrayProxy.extend({
  content: [],
  createObject: function(hash) {
    var dataSource = this.get('dataSource');
    dataSource.createObject(hash, this, this.createdObject);
  },
  createdObject: function(object) {
    this.pushObject(object);
  }
});

的DataSource:

App.DataSource = Ember.Object.extend({
  createObject: function(hash, target, callback) {
    Ember.$.ajax({
      success: function(data) {
        callback.apply(target, data);
      }
    });
  }
});

将所有东西粘在一起:

App.dataSource = App.DataSource.create();
App.listController = App.Controllers.List.create({
  dataSourceBinding: 'App.dataSource'
});

App.View.ItemCreate.create({
  controllerBinding: 'App.listController'
}).append();

答案 1 :(得分:2)

如果您想遵循严格的MVC模型,则永远不应在视图上创建模型,而应在控制器上创建模型。 Ember仍然非常年轻,仍然没有任何已定义的模式,我要做的是将模型设置为视图的内容(正如您已经完成的那样),所有输入都绑定到不同的模型属性。然后按下按钮时:

createButton: function(){
  App.Controllers.List.create(this.get('content')); 
}

在控制器上:

create: function(model) {
  if model.valid() { //validates the model
    model.save({
      onSuccess: function(response) { // callback
        var item = App.Models.Item.create(response.item)
        App.controllers.List.add(item)
      }
    })
  }

最后是模特:

save: function(options) {
  $.ajax({
    type: 'POST',
    url: '/test/data.json',
    data: item,
    dataType: 'json',
    success: options.onsuccess
  });
}

这是其他js框架期望你工作的方式。它感觉有点冗长和复杂,但它保持了适当的位置