31

我有一个非常简单的 CRUD 应用程序,它允许创建新对象以及编辑它们。

用于添加记录和编辑记录的模板几乎相同。

它们使用完全相同的表单元素。唯一的区别是表单下方的标题和按钮(应该更新或创建记录)

在我的实现中,我有

  • 2 路线定义
  • 2个路线对象
  • 2个控制器对象
  • 2个模板

我想知道如果

  • 我不能在这里推广重用
  • 如果需要所有这些对象。

有什么困扰我:

  • 我有 2 个用于创建和编辑的单独模板(虽然它们几乎相同)
  • 我有 2 个独立的控制器做同样的事情。

我希望在控制器级别解决这个问题。当控制器装饰模型时,在我的例子中,1 个控制器对象可以包装新记录或现有记录。然后它可以公开一个属性(isNewObject),以便模板可以决定我们是在“新”还是“编辑”流中。控制器可以有一个new在场景和update场景中都有效的 createOrUpdate 方法。

路线

当前的实现正在为我的资源使用一个新的和一个编辑路由。

this.resource("locations", function(){
  this.route("new", {path:"/new"});
  this.route("edit", {path: "/:location_id" });
});

新路线

new route负责创建新记录,并在用户导航到新记录屏幕时调用。

App.LocationsNewRoute = Ember.Route.extend({
  model: function() {
    return App.Location.createRecord();
  }
});

编辑路线

edit route用户单击概览屏幕中的编辑按钮时,它负责编辑现有对象。我没有扩展默认的编辑路线,而是使用自动生成的路线。

控制器

和控制器负责处理模板中发生的操作(保存或更新记录newedit

两个控制器唯一要做的就是提交事务。

注意:我想这是一个可重复使用的候选对象,但是如何使用单个控制器来驱动 2 个不同的路线/模板?

App.LocationsNewController = Ember.ObjectController.extend({
  addItem: function(location) {
    location.transaction.commit();
    this.get("target").transitionTo("locations");
  }
});

App.LocationsEditController = Ember.ObjectController.extend({
  updateItem: function(location) {
    location.transaction.commit();
    this.get("target").transitionTo("locations");
  }
});

模板:

如您所见,我这里唯一的代码重用是部分(模型字段绑定)。我还有 2 个控制器(新的和编辑的)和 2 个模板。

新模板设置正确的标题/按钮并重新使用表单部分。

<script type="text/x-handlebars" data-template-name="locations/new" >
    <h1>New location</h1>
    {{partial "locationForm"}}
    <p><button {{action addItem this}}>Add record</button></p>
</script>

编辑模板设置正确的标题/按钮并重新使用表单部分。

<script type="text/x-handlebars" data-template-name="locations/edit" >
    <h1>Edit location</h1>
    {{partial "locationForm"}}
    <p><button {{action updateItem this}}>Update record</button></p>
</script>

部分的

<script type="text/x-handlebars" data-template-name="_locationForm" >
  <form class="form-horizontal">
  <div class="control-group">
    <label class="control-label" for="latitude">Latitude</label>
    <div class="controls">
      {{view Ember.TextField valueBinding="latitude"}}
    </div>
  </div>
  <div class="control-group">
    <label class="control-label" for="latitude">Longitude</label>
    <div class="controls">
      {{view Ember.TextField valueBinding="longitude"}}
    </div>
  </div>
  <div class="control-group">
    <label class="control-label" for="accuracy">Accuracy</label>
    <div class="controls">
      {{view Ember.TextField valueBinding="accuracy"}}
    </div>
  </div>
</form>
</script>

注意:我希望我可以在这里做一些更高效/更聪明的事情。

我希望我的模板看起来像这样:(从控制器获取标题,并有一个处理更新和创建的单一操作)

<script type="text/x-handlebars" data-template-name="locations" >
    <h1>{{title}}</h1>
    {{partial "locationForm"}}
    <p><button {{action createOrUpdateItem this}}>Add record</button></p>
</script>

问题

我是否可以重新处理此代码以实现更多代码重用,或者尝试使用单个模板和单个控制器为“编辑记录”和“新记录”流执行此操作是一个坏主意。如果是这样,如何做到这一点?我错过了我的 2 条路线(创建和编辑)将重新使用相同的控制器/模板的部分。

4

2 回答 2

28

你自始至终都是对的。

您也可以使用新的控制器和模板edit route

你只需要做两件事。

首先renderTemplateedit route.

App.LocationsEditRoute = Ember.Route.extend({
  setupController: function(controller, model) {
    this.controllerFor('locations.new').setProperties({isNew:false,content:model});
  },
  renderTemplate: function() {
    this.render('locations/new')         
  }
});

随着新模板的呈现,控制器也将被呈现newController,并且您可以让动作指向newController.

如果要更改标题和按钮文本,可以将它们作为计算属性观察isNew属性。

希望这可以帮助。

PS:不要忘记将isNew属性设置为setupControllertruenew route

于 2013-05-02T10:46:10.840 回答
2

用这个:

App.YourNewRoute = Em.Route.extend ({
   controllerName: 'controllerName',
   templateName: 'templateName'
 });

仅使用 homeController 用户“home”之类的初始名称。

例子:

App.YourNewRoute =  Em.Route.extend ({
   controllerName: 'home',
   templateName: 'home'
});

现在您可以使用“home”的模板和控制器方法。

于 2015-08-07T13:14:53.080 回答