Ember.js控制器&查看绑定(ember.js方式......)

时间:2013-03-21 18:57:15

标签: javascript ajax ember.js sinatra

我为这个问题的篇幅道歉,但我缺乏使其缩短的洞察力。

我正在努力学习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;花时间阅读这个相当长的问题。

1 个答案:

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