Ember.js EmberJS-为不同路线共享控制器/模板
我有一个非常简单的CRUD应用程序,它允许创建新对象以及编辑它们 用于添加记录和编辑记录的模板几乎相同 它们使用完全相同的表单元素。 唯一的区别是表单下方的标题和按钮(应该更新或创建记录) 在我的实现中,我有Ember.js EmberJS-为不同路线共享控制器/模板,ember.js,Ember.js,我有一个非常简单的CRUD应用程序,它允许创建新对象以及编辑它们 用于添加记录和编辑记录的模板几乎相同 它们使用完全相同的表单元素。 唯一的区别是表单下方的标题和按钮(应该更新或创建记录) 在我的实现中,我有 2路线定义 2路由对象 2控制器对象 2个模板 我想知道 我不能在这里提倡重复使用 如果所有这些对象都是必需的 困扰我的是: 我有两个单独的模板用于创建和编辑(虽然它们几乎相同) 我有两个独立的控制器,它们做完全相同的事情 我希望在控制器层面上解决这个问题。 当控制器装饰模型时
- 2路线定义
- 2路由对象
- 2控制器对象
- 2个模板
- 我不能在这里提倡重复使用
- 如果所有这些对象都是必需的李>
- 我有两个单独的模板用于创建和编辑(虽然它们几乎相同)
- 我有两个独立的控制器,它们做完全相同的事情
new
和update
场景中都有效
路线
当前实现正在为我的资源使用新的和编辑路由
this.resource("locations", function(){
this.route("new", {path:"/new"});
this.route("edit", {path: "/:location_id" });
});
新路线
newroute
负责创建新记录,并在用户导航到新记录屏幕时调用
App.LocationsNewRoute = Ember.Route.extend({
model: function() {
return App.Location.createRecord();
}
});
编辑路线
编辑路线
负责在用户单击概览屏幕中的编辑按钮时编辑现有对象。
我没有扩展默认的编辑路线,而是使用自动生成的路线
控制器
new
和edit
控制器负责处理模板中发生的操作(保存或更新记录)
两个控制器唯一要做的就是提交事务
注意:我想这是一个可重复使用的候选控制器,但是如何使用一个控制器来驱动两个不同的路线/模板
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>
新位置
{{partial“locationForm”}
添加记录
编辑模板设置正确的标题/按钮,并重新使用表单部分
<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>
编辑位置
{{partial“locationForm”}
更新记录
部分
<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>
纬度
{{view Ember.TextField valueBinding=“latitude”}
经度
{{view Ember.TextField valueBinding=“longitude”}
精确
{{view Ember.TextField valueBinding=“accurity”}
注意:我希望我能在这里做一些更有效率/更聪明的事情
我希望我的模板如下所示:(从控制器获取标题,并有一个操作来处理更新和创建)
{{title}}
{{partial“locationForm”}
添加记录
问题:
我是否可以重新处理此代码以实现更多的代码重用,或者尝试对“编辑记录”和“新记录”流使用单个模板和单个控制器来执行此操作是一个坏主意。
如果是,如何做到这一点?我遗漏了我的两条路线(创建和编辑)将重复使用同一控制器/模板的部分。您在整个过程中都是正确的 您还可以在
编辑路线
中使用新的控制器和模板
你只需要做两件事
首先,在edit route
的renderTemplate
钩子中,将模板名称设为new
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
属性
希望这有帮助
注意:不要忘记在新路线的设置控制器中将isNew属性设置为true使用以下方法:
App.YourNewRoute = Em.Route.extend ({
controllerName: 'controllerName',
templateName: 'templateName'
});
仅使用homeController用户“home”的首字母名称,仅此而已
例如:
App.YourNewRoute = Em.Route.extend ({
controllerName: 'home',
templateName: 'home'
});
现在您可以使用“主页”的模板和控制器方法了。太好了!看起来很好用。。。我猜你的setProperties通话中有一个小错误。。。必须传递一个JSON结构,该结构嵌入了我想要更新的所有属性:setProperties({isNew:false,content:model}出色的问答!如果需要跨资源的同名路由,请尝试以下线程:在这种情况下,我如何使用相同的控制器但使用不同的模板(如edit)?我的模板70%相同,但希望将它们分开,但我可以使用相同的控制器并可以签入它们,根据模板加载哪些数据。谢谢添加答案,虽然这可能有效,但有点过时,现在更好的方法是将模板和代码组件化。@Kingpin2k我知道这是一个有点陈旧的注释和答案,但我正在自学EmberJS,在我使用EmberCLI设置的框架中,似乎使用templateName:'home'
和renderTemplate:function(){this.render('home')}
表面上的工作原理是一样的。但是renderTemplate
方法似乎更笨拙?但由于EmberJS结构,这是现在所需要的行为?可能会基于此提出一个新问题,但如果可以提供,请简单说明。