2016-03-31 13 views
0

このアプリケーションのhtmlビューには、デフォルトで20に設定された変数が含まれています。この温度は、アプリケーションの実行中にアップ/ブラウザに表示されます。ブラウザまたはページがリフレッシュされ(またはリダイレクト)温度が残っていないが、代わりに、常に20にデータベースを使用しないjson/javascriptを使用してsinatraで状態を保存する方法

ここ

をリセットする場合はビューは次のとおりです。

<!DOCTYPE html> <link href='https://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css'> <html> <head> 
    <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> 
    <section class="display"> 
     <h1>Thermostat</h1> 
     <input id='city' type='text' placeholder="city name"> 
     <button id='submit'>Submit</button> 
     <p id='weather'></p> 
     <h1 id="temperature"></h1> 
     <h4 id="psm"></h4> 
     <form action='/temperature' method='post'> 
     <button class="icon icon-up" id="up" name='temp'></button> 
     <button class="icon icon-down"id="down" name='temp'></button> 
     <button id="reset" name='temp'>reset</button> 
     <button id="switchpowersaving">PSM</button> 
     </form> 
    </section> 
    <script src="jquery.js"></script> 
    <script src="thermostat.js"></script> 
    <script src="interface.js"></script> 
    <script src="weatherAPI.js"></script> </body> </html> 

我々は我々がインデックスに向けられているページにアクセスすると。ここで温度を上げたり下げたりします。温度が変更されるたびに、POSTメソッドが/ temperatureページに送られます。これにより、JSON、セッション、およびパラメータを使用してハッシュが作成されます。 interface.jsファイルには、この新しい温度をdata.tempとして保存するajax GET関数があります。これにより、ページがリロードされるたびに、サーモスタットの温度が保存されたdata.tempに設定されます。ここで

$(document).ready(function() { 

    var thermostat = new Thermostat(); 
    var temp = thermostat.temperature; 

    $.ajax({ 
    type: 'GET', 
    url: 'http://localhost:4567/temperature', 
    success: function(data){ 
     temp = data.temp; 
    }, 
    error: function(){ 
     alert('Error loading temp'); 
    } 
    }); 

    updateTemperature(); 

    $('#up').click(function() { 
    thermostat.increaseTemperature(); 
    updateTemperature(); 
    }); 

    $('#down').click(function() { 
    thermostat.decreaseTemperature(); 
    updateTemperature(); 
    }); 

    $('#reset').click(function() { 
     thermostat.tempReset(); 
     updateTemperature(); 
    }); 

    $('#switchpowersaving').click(function() { 
    thermostat.switchModePowerSaving(); 
    updateTemperature(); 
    }); 

    function updateTemperature() { 
    $('#temperature').text(thermostat.currentTemperature() + "\xB0C"); 
    $('#up').attr('value', thermostat.currentTemperature()); 
    $('#down').attr('value', thermostat.currentTemperature()); 
    $('#reset').attr('value', thermostat.currentTemperature()); 
    $('.display').css('background-color', thermostat.displayColor()); 
    $('#psm').text(thermostat.displayPowerSaveMode()); 
    } 
}); 

がthermostat.jsです:

function Thermostat(){ 
    this.temperature = 20; 
    this.MINTEMP = 10; 
    this.isPowerSaving = true; 
    this.thermostatDisplay = 'yellow'; 
} 

Thermostat.prototype.currentTemperature = function(){ 
    return this.temperature; 
}; 

Thermostat.prototype.increaseTemperature = function(){ 
    if (this.currentTemperature() >= this.maxTemp()) { 
    throw 'Max. temp reached'; 
} 
    this.temperature ++; 
}; 

Thermostat.prototype.decreaseTemperature = function(){ 
    if (this.currentTemperature() <= this.MINTEMP) { 
    throw 'Min. temp reached'; 
    } 
    this.temperature --; 
}; 

Thermostat.prototype.maxTemp = function(){ 
    if(this.isPowerSaving === true) {return 25;} 
    else 
     {return 32;} 
}; 

Thermostat.prototype.switchModePowerSaving = function() { 
    if (this.isPowerSaving === true) 
    {this.isPowerSaving=false;} 
    else 
    {this.isPowerSaving=true;} 
}; 

Thermostat.prototype.tempReset = function() { 
    this.temperature = 20; 
}; 

Thermostat.prototype.displayColor = function() { 
    if(this.temperature <= 18) {return 'green';} 
    if(this.temperature <= 25) {return 'yellow';} 
    if(this.temperature > 25) {return 'red';} 
}; 

Thermostat.prototype.displayPowerSaveMode = function(){ 
    if(this.isPowerSaving === true) {return 'Power Save Mode: ON';} 
    else {return 'Power Save Mode: OFF';} 
}; 
ここ

require 'sinatra' 
require 'json' 

enable :sessions 

    get '/' do 
    send_file 'views/index.html' 
    end 

    post '/temperature' do 
    p params[:temp] 
    session[:temp] = params[:temp].to_i 
    redirect '/temperature' 
    end 

    get '/temperature' do 
    p session[:temp] 
    if session[:temp] 
     JSON.generate({temp: session[:temp]}) 
    else 
     JSON.generate({temp: 20}) 
    end 
    redirect '/' 
    end 

はinterface.jsファイルです。しかし、それが継続的にこれはコントローラである20

にリセットされます

increaseTemperature/declineTemperature関数は、サーモスタットの温度を+1だけ増減します/ -1。

ボタンを押したときの新しい温度は、ブラウザの '/ temperature'に直接アクセスするとアクセスできますが、新しいサーモスタットが '/'にリダイレクトされて新しい温度に設定されず、常にデフォルト温度(20)。

データベースを使用せずにこれをどのように状態に保存することができますか。ページが更新されたときに(新しい温度を保管してくださいので、新しい温度ではなく、ここ20

+0

フォームは提出されていますか?なぜリアルタイムで温度を更新するのに$ .ajaxを使用しないのですか? – jjm

+0

以前はリアルタイムで温度が更新されていましたが、コントローラは必要ありませんでしたが、ブラウザをリフレッシュするときに、サーモスタットがリフレッシュされて保存および取得される前の温度が必要でした。 (フォームはajax.getスクリプトなしで実行されます)これは保存目的でのみ追加されました) –

+0

Hmmので、SinatraセッションはCookieに保存されます。おそらくあなたはあなたのブラウザでそれらを無効にしていますか?あなたのローカルドメインのCookieが設定されていることを確認できますか? – jjm

答えて

0

に問題のカップルをリセットするよりも、残っている:

send_fileはシナトラを使用してHTMLファイルをロードする好ましい方法ではありません。

get '/' do 
    erb :index 
end 

ERBは、HTMLのスーパーセットであるとシナトラから変数を渡すために使用されるか、または単純に実行することができルビー補間タグを追加します。これに代わるものはindex.erbindex.htmlの名前を変更して、ルート記述子として以下を使用することですルビーの命令w。これらのタグは、JSPの<%%>またはPHPの<?php ?>に似ています。 ERBでは、<%%>はrubyコマンドを実行し、<%= %>を使用してrubyコマンドの結果をビューに出力することができます。

ルートを設計する際に、要求/応答のデータタイプを事前に把握することが重要です。たとえば、interface.jsがロードされると、エンドポイント'/temperatureにjQuery経由でGETリクエストが送信されます。データ型を指定していないので、応答は文字列になり、data.tempnullになります。だから、AJAX呼び出しでは、あなたはdataType: 'json'設定を追加する必要があるだろう:行うには

$.ajax({ 
    type: 'GET', 
    url: 'http://localhost:4567/temperature', 
    dataType: 'json', 
    success: function(data){ 
    // same as earlier 
}); 

もう一つの良いところは、AJAX呼び出しとシナトラでredirect呼び出しを混在し、一致しないことです。これは特にこの場合、インデックスページにリダイレクトすると、セッションデータが存在しても、どこにもロード/表示されないためです。理想的には、シナトラに、インスタンス変数に値を代入し、ビューでそれをプリントアウトする必要があると思います:

# app.rb 
get '/' do 
    @temp = session[:temp] || 20 
    erb :index 
end 

# views/index.erb 
# truncating common code 
<h1 id="temperature"><%= @temp %></h1> 

そうすれば、get '/'ルート負荷が、初期温度が表示されるとき。 $.ajaxGETリクエストは完全に削除できます。

ボタンをクリックすると、デフォルトでフォームが送信され、完全にリロードされます。これはあなたがやっているすべてのJSベースのレンダリングで混乱することがあります(私はその部分を今のところ完全に理解できません)。だから、フルページリダイレクトをする代わりに、AJAXの投稿(コメントの中で指摘されているような)を '/ temperature'ルートにする方が良いでしょう。ボタンクリックのデフォルトアクションを無効にする必要があることに注意してください。だから、:これはデフォルトのHTMLフォームを使用して、ボタンをクリックしたときに発生しません提出することを保証します

$('#up').click(function(event) { 
    event.preventDefault(); 
    event.stopPropagation(); 
    thermostat.increaseTemperature(); 
    updateTemperature(); 
    }); 

$('#up').click(function() { 
    thermostat.increaseTemperature(); 
    updateTemperature(); 
    }); 

およびその他のクリックハンドラに変更する必要があります。 updateTemperature()はajax POST呼び出しを行います。私はここにサンプルを載せました:https://gist.github.com/kgrz/9320d1682e682a9930c30e34c979a306

+0

私はあなたの構文をしかし、私たちがページをリロードすると、索引にセッションがないかのように見えます:temp、これは以前のようにデフォルトで20になります。@Kashyap –

+0

ajax.post関数がparams [:temp]を継承しているとは思えません。 –

関連する問題