创建新模型的正确控制器/视图模式是什么

what is the correct controller/view pattern for creating a new model

本文关键字:控制器 视图 是什么 模式 新模型 模型 创建      更新时间:2023-09-26

我有一个应用程序,目前包含同一模型对象的视图。它们从服务器检索,循环并使用 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提供的答案,因为它不仅是一个很好的MVC,而且它更Ember-y :o)

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

案例的工作流可能如下所示:

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

您还应该查看 ember-data,它是一个客户端数据存储,并为您处理所有样板文件。还可以看看 Ember.js apps 的架构 - data 和 EmberJS:在一个相当复杂的应用程序中很好地分离了模型、商店、控制器、视图的关注点?


视图:

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);
  }
});

数据来源:

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();

如果要遵循严格的 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框架期望你的工作方式。感觉有点冗长和复杂,但它使事情保持原位