我为这个问题的篇幅道歉,但我缺乏使其缩短的洞察力。
我正在努力学习Ember.js&我在理解控制器之间的关系方面遇到了一些麻烦。特别是因为它涉及控制器属性和查看绑定。我有一个工作的应用程序 ...但我真的不明白为什么&我觉得(很明显)这不是'Ember.js'的方法。
需要考虑的一些事项:根据我在指南/文档中解释的“正确”结构,将此应用程序分解为目录/文件。此应用程序在sinatra应用程序的上下文中运行。这个应用虽然不完整,但确实按照我预期的方式工作。
申请表不完整,但这里概述了我的期望和目的。我想做什么:
1)用户到达根网址“/”并转换为“/ locate”网址。
2)LocateController抓取用户位置,用lat / lng填充两个表单字段。
3)表单以ajax的形式作为POST提交给sinatra'/ locate'路由。
(请求由服务器处理)
4)用户转换到ember.js'#/ located'路线。
5)信息作为JSON对象从服务器返回。显示
到目前为止,我只实施了第一步。如果我添加了一个提交按钮,可以发送表单,但想法是让它自动发生。
使用表单字段的正确值填充locate视图中的字段。但是,我使用直接jQuery更新值,对我来说似乎不是在ember.js应用程序中执行此操作的“正确”方法
以下是我的一些代码。为了简洁起见,我将提供一些片段,如果您知道正确的答案,您将能够从提供的摘录中获得它。
我的观点设置如下: 我在我的sinatra应用程序中使用slim
script type="text/x-handlebars" data-template-name="application"
| {{ outlet }}
script type="text/x-handlebars" data-template-name="locate"
| {{ message }}
| <form id="coordinates">
| {{view Ember.TextField id="latitude" name="latitude" valueBinding="latitude" class="latitude"}}
| {{view Ember.TextField id="longitude" name="longitude" valueBinding="longitude" class="longitude"}}
| </form>
script type="text/x-handlebars" data-template-name="located"
| <p id="message">{{ message }}</p>
| <p id="latitude">{{ latitude }}</p>
| <p id="longitude">{{ longitude }}</p>
script src =“assets / js / app / application.js”
applicationView.js
Application.ApplicationView = Ember.View.extend({
templateName: 'application'
});
Application.LocateView = ApplicationView.extend({
templateName: 'locate'
});
Application.LocatedView = ApplicationView.extend({
templateName: 'located'
});
applicationController.js
var GeoLocation;
GeoLocation = (function(location){
$('#latitude').val(location.coords.latitude),
$('#longitude').val(location.coords.longitude)
});
navigator.geolocation.getCurrentPosition(GeoLocation)
Application.ApplicationController = Ember.Controller.extend({
message: "Hello from Application"
});
Application.LocateController = Ember.Controller.extend({
message: "Hello from Locate",
latitude: "-- lat --",
longitude: "-- lng --",
});
Application.LocatedController = Ember.Controller.extend({
message: "Hello from Located",
latitude: "-- lat --",
longitude: "-- lng --",
});
router.js
Application.Router.map(function() {
this.route('index');
this.route('locate');
this.route('located');
});
Application.ApplicationRoute = Ember.Route.extend({
events: {
goToLocate: function() {
this.transitionTo('locate');
},
goToLocated: function() {
this.transitionTo('located');
}
}
});
Application.IndexRoute = Ember.Route.extend({
redirect: function() {
this.render('application');
this.transitionTo('locate');
}
});
Application.LocateRoute = Ember.Route.extend({
redirect: function() {
this.render('locate');
//this.transitionTo('located');
}
});
});
Application.LocatedRoute = Ember.Route.extend({
renderTemplate: function(controller) {
this.render('located');
}
});
我已阅读指南&amp; ember.js网站上的API文档以及GitHub上的repo。我觉得“正确”的实现会使用纬度和算法的计算属性。经度属性,但我不太明白它在实践中是如何工作的。
另外,我知道很有可能有更好的方法来处理将信息传递到服务器(当我到达目的地时可能是JSON或者ember-data?),并且可以随意分享您可能拥有的任何见解对此。但是现在,由于我对sinatra以及它如何工作感到满意,我宁愿选择一种不需要对我的后端进行重大重构的解决方案。 (也就是说,能够从sinatra的参数[:hash]访问位置数据)。
提前感谢您的帮助&amp;花时间阅读这个相当长的问题。
答案 0 :(得分:4)
我同意在ember应用程序中通过jQuery设置输入的值不是可行的方法。 Ember非常适合与属性绑定。 我建议,因为你在初始加载时重定向到定位路由,将getLoaction逻辑移动到LocateController或在路由setupController钩子中设置它看到这里(see here for setupController example) ...你也可以在你的App实例上设置这个属性,如果你想访问它们。
所以,而不是:
var GeoLocation;
GeoLocation = (function(location){
$('#latitude').val(location.coords.latitude),
$('#longitude').val(location.coords.longitude)
});
navigator.geolocation.getCurrentPosition(GeoLocation)
我会在路线上这样做:
App.LocateRoute = Ember.Route.extend({
setupController: function(controller, model) {
navigator.geolocation.getCurrentPosition(controller.geoLocation)
}
});
App.LocateController = Ember.Controller.extend({
geoLocation: function(location){
this.set('latitude', location.coords.latitude);
this.set('longitude', location.coords.longitude);
}
});
现在,您的定位控制器已定义了2个属性“纬度”和“经度”。您可以在模板中绑定它们。 (顺便说一下,你的模板看起来已经正确绑定了。)
您还可以在App实例上设置此属性,如果您想要全局访问它们,则将绑定更改为指向“App.longitude”和“App.latitude”。
App.LocateController = Ember.Controller.extend({
geoLocation: function(location){
Ember.set(App, 'latitude', location.coords.latitude);
Ember.set(App, 'longitude', location.coords.longitude);
}
});