2

この質問が長くなって申し訳ありませんが、短くするための洞察が不足しています。

私は Ember.js を学習しようとしています & ビューであるコントローラー間の関係を理解するのに少し問題があります。特に、コントローラーのプロパティとビューのバインディングに関連する場合。動作するアプリケーションが少しあります...しかし、その理由がよくわかりません. (むしろ明らかに)これは「Ember.js」の方法ではないと思います.

考慮すべき点: このアプリケーションは、ガイド/ドキュメントで「正しい」構造であると解釈した内容に従って、ディレクトリ/ファイルに分割されています。このアプリケーションは、sinatra アプリケーションのコンテキストで実行されています。このアプリケーションは不完全ですが、これまでのところ期待どおりに動作します。

アプリケーションは不完全ですが、ここに私が期待することと私がやろうとしていることの一般的な概要があります:

1) ユーザーがルート URL「/」に到達し、「/locate」URL に遷移します。

2) LocateController はユーザーの位置を取得し、2 つのフォーム フィールドに緯度/経度を入力します。

3) フォームは ajax として sinatra '/locate' ルートへの POST としてサーバーに送信されます。

(リクエストはサーバーによって処理されます)

4) ユーザーは ember.js の「#/located」ルートに遷移します。

5) サーバーから情報が JSON オブジェクトとして返され、表示されます

これまでのところ、ステップ 1 のみを実装しました。送信ボタンを追加するとフォームを送信できますが、自動的に送信されるようにするという考えです。

検索ビューのフィールドには、フォーム フィールドの正しい値が入力されます。ただし、私はストレート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>

スクリプト 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');
  }
});

ember.js Web サイトのガイドと API ドキュメントを読み、GitHub のリポジトリを見ました。「正しい」実装では、緯度と経度の属性に計算されたプロパティを使用するように感じますが、それが実際にどのように機能するかはよくわかりません。

また、サーバーに情報を取得するためのより良い方法がある可能性が高いことも知っています (おそらく、そこまで到達した場合は JSON または ember-data として)。それに関する洞察を自由に共有してください。しかし今のところ、私はsinatraとその仕組みに慣れているので、バックエンドの大規模なリファクタリングをまだ必要としないソリューションを好みます. (つまり、sinatra の params[:hash] から位置データにアクセスできること)。

このかなり長い質問をお読みいただき、ご協力いただきありがとうございます。

4

1 に答える 1

4

私は、残り火アプリでjQueryを介して入力の値を設定することが方法ではないことに同意します。Emberは、プロパティへのバインドに非常に適しています。初期ロード時にLocaterouteにリダイレクトするので、getLoactionロジックをLocateControllerに移動するか、ルートsetupControllerフック内に設定することをお勧めします(setupControllerの例についてはこちらを参照) ...これは、それらにアクセスしたい場合は、アプリインスタンス。

したがって、これの代わりに:

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

これで、Locateコントローラーに「latitude」と「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);
  }
});
于 2013-03-21T20:11:08.540 に答える