简体   繁体   English

Ember.js控制器和视图绑定(ember.js方式…)

[英]Ember.js Controller & View Binding (The ember.js way…)

I apologize for the length of this question but I lack the insight to make it short. 对于这个问题的长度,我深表歉意,但我缺乏使它简短的见识。

I am trying to learn Ember.js & I am having a little trouble understanding the relationship between a controller it's view. 我正在尝试学习Ember.js,并且在理解它所查看的控制器之间的关系时遇到了一些麻烦。 Particularly as it relates to controller property & view bindings. 特别是与控制器属性和视图绑定有关。 I have a bit of an application that works ... But I don't really understand why & I feel that (rather obviously) this is not the 'Ember.js' way to do it. 我有一个可以正常工作的应用程序。。。但是我真的不明白为什么,我(显然)不是“ Ember.js”方法。

Some things to consider: This application is broken out into directory/files according to what I have interpreted in the guides/documentation to be the 'correct' structure, This application is running in the context of a sinatra application. 需要考虑的一些事情:根据我在指南/文档中解释为“正确”的结构,此应用程序分为目录/文件,该应用程序在sinatra应用程序的上下文中运行。 This application, although incomplete, does work the way I expect it to so far. 该应用程序虽然不完整,但确实可以达到我期望的方式。

The application is incomplete but here is a general overview of what I expect & what I am trying to do: 该应用程序是不完整的,但是这里是我期望和我想做的事情的一般概述:

1) A user arrives at the root URL '/' and is transitioned to the '/locate' URL. 1)用户到达根URL“ /”,并转换为“ / locate” URL。

2) The LocateController grabs the users location, populates two form fields with the lat/lng. 2)LocateController抓住用户位置,用lat / lng填充两个表单字段。

3) The form is submitted to the server as POST to the sinatra '/locate' route as ajax. 3)表单以ajax的形式提交到sinatra'/ locate'路由的POST到服务器。

(request is processed by server) (请求由服务器处理)

4) User is transitioned to the ember.js '#/located' route. 4)用户被转换到ember.js的“#/ located”路由。

5) Information comes back from the server as a JSON object & displayed 5)信息作为JSON对象从服务器返回并显示

I have thus far only implemented step one. 到目前为止,我只执行了第一步。 The form could be sent if I added a submit button but the idea is to have it happen automatically. 如果我添加了一个提交按钮,则可以发送该表单,但想法是使其自动发生。

The fields in the locate view are populated with the correct values for the form fields. 在定位视图中的字段将使用表单字段的正确值填充。 However, I am using straight jQuery to update the values and that to me seems like it is not the 'correct' way to do this in an ember.js app 但是,我正在使用简单的jQuery更新值,对我来说,这似乎不是在ember.js应用中执行此操作的“正确”方法

Here follows some of my code. 这是我的一些代码。 For the sake of brevity I will just provide snippets as I feel like if you know the right answer you will be able to derive it from the provided excerpts. 为了简洁起见,我只提供摘要,就像您知道正确的答案一样,您可以从提供的摘录中得出摘要。

My views are set up like this: I use slim in my sinatra app 我的视图设置如下: 我在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" 脚本src =“ assets / js / app / application.js”

applicationView.js applicationView.js

Application.ApplicationView = Ember.View.extend({
  templateName: 'application'
});

Application.LocateView = ApplicationView.extend({
  templateName: 'locate'
});

Application.LocatedView = ApplicationView.extend({
  templateName: 'located'
});

applicationController.js 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 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');
  }
});

I have read the Guides & The API Documentation on the ember.js website as well as looked at the repo on GitHub. 我已经阅读了ember.js网站上的指南和API文档,并查看了GitHub上的回购协议。 I feel like the 'correct' implementation would use computed properties for the latitude & longitude attributes but I don't quite understand how that works in practice. 我觉得“正确”的实现将对纬度和经度属性使用计算的属性,但是我不太了解它在实践中是如何工作的。

Also, I know that there is most likely a better way to deal with getting the information to the server (perhaps as JSON or ember-data when I get that far?), and feel free to share any insights you may have regarding that. 另外,我知道,最有可能有一种更好的方法来处理将信息传送到服务器的问题(可能是到达目的地时可能是JSON或ember-data?),并随时分享您对此的任何见解。 But for now however, as I am comfortable with sinatra and how it works I would prefer a solution that does not require major refactoring of my backend yet. 但是就目前而言,由于我对sinatra及其工作方式感到满意,因此我希望使用一种不需要对后端进行重大重构的解决方案。 (that is to say, being able to access the location data from sinatra's params[:hash]). (也就是说,能够从sinatra的params [:hash]中访问位置数据)。

Thanks in advance for your help & taking the time to read this rather long question. 在此先感谢您的帮助,并抽出宝贵的时间阅读此较长的问题。

I do agree that setting the value of an input via jQuery in an ember app is not the way to go. 我确实同意,在余烬应用程序中通过jQuery设置输入值不是可行的方法。 Ember does really well with binding to properties. Ember在绑定属性方面确实做得很好。 I would suggest that since you redirect to Locate route on initial load, move the getLoaction logic to the LocateController or set it inside the route setupController hook see here (see here for setupController example) ... You can also set the properties this on your App instance, if you wanted to have access to them. 我建议,由于您在初始加载时重定向到定位路由,请将getLoaction逻辑移至LocateController或将其设置在路由setupController挂钩中(请参阅此处(关于setupController的示例)) ...您也可以在自己的服务器上设置此属性应用实例,如果您想访问它们。

So, instead of this: 因此,代替此:

var GeoLocation;

GeoLocation = (function(location){
    $('#latitude').val(location.coords.latitude),
    $('#longitude').val(location.coords.longitude)
});

navigator.geolocation.getCurrentPosition(GeoLocation)

I would do it in the route: 我会在路线上这样做:

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

Now your Locate controller has the 2 properties 'latitude' and 'longitude' defined. 现在,您的“定位”控制器已定义了两个属性“纬度”和“经度”。 You can bind to them in your template. 您可以在模板中绑定它们。 (BTW, your template already look correct for the binding.) (顺便说一句,您的模板对于绑定而言已经看起来正确。)

You can also set the properties this on your App instance, if you wanted to have access to them globally, then change the bindings to point to 'App.longitude' and 'App.latitude'. 您还可以在您的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);
  }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM