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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10242467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 09:10:17  来源:igfitidea点击:

ember.js - what is the correct controller/view pattern for creating a new model

javascriptember.js

提问by joevallender

I have an app which at the moment contains a view of objects of the same model. They are retrieved from the server, looped through and added to the list controller using an add method

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

<script>
App.Controllers.List = Em.ArrayProxy.create({
  content: Ember.A([]),
  add: function(obj){
    this.pushObject(obj);
  }
});
</script>

I am now working on a part where the user creates a new object that (after passing validation) will be added to the list and also sent to the server.

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

I can't find any examples on the best patter to follow for creating a new object via an input form. I can see a few options, and have semi-implemented a few but nothing feels right.

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

  • Create a view with appropriate form elements and a method for instantiating the model using various properties retrieved from the form elements using .get()
  • Create a model in the view's content and bind form elements to that. Include a method on the view for adding to the controller array / saving to the server
  • Create a model, add it to the controller array and open it for editing
  • 使用适当的表单元素创建一个视图,并使用使用 .get() 从表单元素检索的各种属性来实例化模型的方法
  • 在视图的内容中创建一个模型并将表单元素绑定到该模型。在视图中包含一个用于添加到控制器阵列/保存到服务器的方法
  • 创建一个模型,将它添加到控制器数组中并打开它进行编辑

I can kind of fight out the functionality I want, but I'd prefer make sure I am aware of best practice.

我可以争取我想要的功能,但我更愿意确保我了解最佳实践。

I currently have something like this (which is the second bullet on my list)

我目前有这样的东西(这是我列表中的第二个项目符号)

<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>

Any help greatly appreciated

非常感谢任何帮助

NOTES

笔记

I've changed the correct answer to pangratz's. Although the other responses directly answered my question, I believe those who find this via Google should refer to the answer Pangratz provided as not only is it good MVC, but it is more Ember-y :o)

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

回答by pangratz

Communicating with the server is definitely something which shouldn't be done in the view. This is something a controller is for. To separate the different parts of the application further, I would even consider implementing a DataSourcewhich handles the AJAX requests. This split makes your application more testable and each components reusable. The concrete connections of view, controller and data source are then realized via bindings.

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

The workflow for your case could be the following:

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

  • The view shows your edit form, which' values are bound to a controller
  • The view handles a save action which tells the controller to save the created object
  • The controller delegates the saving to the DataSource which then finally starts the AJAX request
  • The controller is notified when the object has been saved
  • 视图显示您的编辑表单,其中的值绑定到控制器
  • 视图处理保存操作,该操作告诉控制器保存创建的对象
  • 控制器将保存委托给 DataSource,然后最终启动 AJAX 请求
  • 保存对象时通知控制器

You should also look at ember-datawhich is a client side data storage and handles all the boilerplate for you. Also have a look at The architecture of Ember.js apps - dataand EmberJS: Good separation of concerns for Models, Stores, Controllers, Views in a rather complex application?

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



View:

看法:

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

Controller:

控制器:

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

Glue everything together:

把所有东西粘在一起:

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

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

回答by Fernando Diaz Garrido

If you want to follow a strict MVC model then the model should never be created on the view but on the controller. Ember is still very young and still haven't any defined patterns, what I would do is have your model set as the content of the view (as you have already done) with all the inputs bind to the different model attributes. Then when the button is pushed:

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

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

On the controller:

在控制器上:

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

And finally the model:

最后是模型:

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

This is the way other js frameworks expect you to work. It feels a little more verbose and complex, but it keeps the things in place

这是其他 js 框架希望你工作的方式。感觉有点冗长和复杂,但它使事情保持原状