EmberJS - 为不同的路线共享控制器/模板

dde*_*ele 31 ember.js

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

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

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

在我的实施中,我有

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

我想知道是否

  • 我不能在这里推广再利用
  • 如果所有这些对象都是必需的.

困扰我的是什么:

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

我希望在控制器级别上解决这个问题.当控制器装饰模型时,在我的情况下,单个控制器对象可以包装新记录或现有记录.然后它可以公开一个属性(isNewObject),以便模板可以决定我们是在"新"还是"编辑"流程中.控制器可以有一个createOrUpdate方法,该方法newupdate场景中和场景中都可以使用.

路线

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

this.resource("locations", function(){
  this.route("new", {path:"/new"});
  this.route("edit", {path: "/:location_id" });
});
Run Code Online (Sandbox Code Playgroud)

新的路线

new route负责创建一个新的记录,当用户导航到新的记录画面被调用.

App.LocationsNewRoute = Ember.Route.extend({
  model: function() {
    return App.Location.createRecord();
  }
});
Run Code Online (Sandbox Code Playgroud)

编辑路线

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");
  }
});
Run Code Online (Sandbox Code Playgroud)

模板:

如您所见,我在这里唯一的代码重用是partial(模型字段绑定).我仍然有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>
Run Code Online (Sandbox Code Playgroud)

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

<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>
Run Code Online (Sandbox Code Playgroud)

部分

<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>
Run Code Online (Sandbox Code Playgroud)

注意:我希望我能在这里做一些有效/更聪明的事情.

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

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

我可以重新使用此代码以获得更多的代码重用,或者尝试使用单个模板和单个控制器对"编辑记录"和"新记录"流进行此操作是一个坏主意.如果是这样,怎么办呢?我错过了我的2条路线(创建和编辑)将重复使用相同控制器/模板的部分.

Hyd*_*der 28

你是对的.

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

你只需做两件事.

首先将模板名称作为新的renderTemplate钩子edit 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')         
  }
});
Run Code Online (Sandbox Code Playgroud)

在渲染新模板时,控制器也将是newController,并且您可以将操作指向中的事件newController.

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

希望这可以帮助.

PS:不要忘记到是否新款属性设置为True setupControllernew route