python使っているとき、easy_installやpipでパッケージをインストールするときに
エラーがvcvarsall.batエラーが出てくる。
簡単な解決方法はVC2008を入れれば良いのだが、
今現在となるとかなり前のバージョンになるから最新版を使えるようにしたいところ。
ということで探してみたら、
distutils\msvc9compiler.pyのfind_vcvarsall関数で取得している事が分かった。
この中でやっていることはレジストリ情報からvsvarsall.batのありかを調べているので
現在使っているコンパイラでvcvarsall.batのあるパスを読み込むようにすればよい。
まずは、
from distutils.msvc9compiler import *
get_build_version()
これで現在のバージョンを調べる。
10.0なら
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\VisualStudio\10.0\Setup\VC\ProductDir
ここに文字列で
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC
を入れて、
find_vcvarsall()を実行してみて、
ちゃんと戻り値が得られている事をチェックする。
これで完了。
インターネット上にある断片化された情報を切り取って、リブログする。 主にソフトウェア、Ubuntu関連、CPUなど気になったニュース、また、日々の面白い出来事やニュースもリブログします。
2013年3月13日水曜日
2013年2月8日金曜日
逆ポーランド記法による演算
.NETならReflectionなどを使って解決する方法もあるけど、
もっと軽量なものがほしいなと思って、逆ポーランド記法による演算をやってみた。
どのようなものができたかというと、基本的な四則演算と、括弧による優先度、変数を扱えるようなもの。
ポイントは3つ。
・括弧内演算は、再帰処理によって実現した。
・四則演算は、優先度を設けて「+-」は最後、「*/」は最初に演算するようにした。
・変数は、逆ポーランドで演算前に、デコード処理を行うようにした。
どっちがいいかは不明。
もっと軽量なものがほしいなと思って、逆ポーランド記法による演算をやってみた。
どのようなものができたかというと、基本的な四則演算と、括弧による優先度、変数を扱えるようなもの。
ポイントは3つ。
・括弧内演算は、再帰処理によって実現した。
・四則演算は、優先度を設けて「+-」は最後、「*/」は最初に演算するようにした。
・変数は、逆ポーランドで演算前に、デコード処理を行うようにした。
Public Sub New()
Console.WriteLine(Calc("1+2-3"))
Console.WriteLine(Calc("1+2*3"))
Console.WriteLine(Calc("(1+2)*3"))
Console.WriteLine(Calc("(1+2)/3"))
End Sub
Module ReversePolishNotation
Private param As New Dictionary(Of String, Integer) '変数
Private dat As String = "" '計算する文字データ
Private idx As Integer = 0 '解析インデックス
Private stk As New Queue(Of String) '後置記法バッファ
Public Function Calc(ByVal data As String) As Integer
dat = data
idx = 0
stk.Clear()
INtoPN() '中置記法→後置記法へ変換
Return RPN() '逆ポーランド記法による演算
End Function
Private Sub INtoPN()
'中置記法→後置記法へ変換
Dim L1 As New Queue(Of String) '後置記法確定バッファ
Dim R1 As New Stack(Of String) '符号格納バッファ
Dim wrd As String = "" '切り出した文字列
Dim hugo As String = "" '優先される符号格納(「*、/」)
While dat.Length > idx
Dim tmp As String = CStr(dat(idx)) 'データ読み出し
idx += 1
Select Case tmp
Case "("
INtoPN() '括弧内優先で演算する
Case ")"
Exit While
Case "+", "-"
'優先度の低い演算子は最後に計算
If wrd <> "" Then L1.Enqueue(wrd)
If hugo <> "" Then L1.Enqueue(hugo)
R1.Push(tmp)
hugo = ""
wrd = ""
Case "*", "/"
'優先度の高い演算子は最初に計算
If wrd <> "" Then L1.Enqueue(wrd)
If hugo <> "" Then L1.Enqueue(hugo)
hugo = tmp
wrd = ""
Case " ", "\t"
'無視するキーワード
Case Else
'演算する文字列
wrd += tmp
End Select
End While
If wrd <> "" Then L1.Enqueue(wrd)
If hugo <> "" Then L1.Enqueue(hugo)
While 0 < L1.Count : stk.Enqueue(L1.Dequeue()) : End While
While 0 < R1.Count : stk.Enqueue(R1.Pop()) : End While
End Sub
Private Function RPN() As Integer
'逆ポーランド記法による演算
Dim dat As New Stack(Of Integer)
While 0 < stk.Count
Dim tmp As String = stk.Dequeue()
Dim R As Integer = stk.Pop()
Dim L As Integer = stk.Pop()
Select Case data
Case "+" : stk.Push(L + R)
Case "-" : stk.Push(L - R)
Case "*" : stk.Push(L * R)
Case "/" : stk.Push(L \ R)
Case Else : dat.Push(Decoder(tmp))
End Select
End While
Return dat.Pop()
End Function
Private Function Decoder(ByVal data As String) As Integer
'変数→数字変換
Dim ret As Integer = 0
If Int32.TryParse(data, ret) Then Return ret
Return param(data)
End Function
End Module
無駄なバッファが多いので、後値記法へ変換しながら演算するようにしてみた。Module ReversePolishNotation
Private param As New Dictionary(Of String, Integer) '変数
Private dat As String = "" '計算する文字データ
Private idx As Integer = 0 '解析インデックス
Private stk As New Stack(Of Integer) '演算バッファ
Public Function Calc(ByVal data As String) As Integer
dat = data
idx = 0
stk.Clear()
RPN() '演算
Return stk.Pop() '結果を返す
End Function
Private Sub RPN()
'中置記法→後置記法へ変換しながら演算を行う
Dim R1 As New Stack(Of String) '符号格納バッファ
Dim wrd As String = "" '切り出した文字列
Dim hugo As String = "" '優先される符号格納(「*、/」)
While dat.Length > idx
Dim tmp As String = CStr(dat(idx)) 'データ読み出し
idx += 1
Select Case tmp
Case "(" : RPN() '括弧内優先で演算する
Case ")" : Exit While
Case "+", "-" '優先度の低い演算子は最後に計算
If wrd <> "" Then stk.Push(Decoder(wrd))
If hugo <> "" Then enzan(hugo)
R1.Push(tmp)
hugo = ""
wrd = ""
Case "*", "/" '優先度の高い演算子は最初に計算
If wrd <> "" Then stk.Push(Decoder(wrd))
If hugo <> "" Then enzan(hugo)
hugo = tmp
wrd = ""
Case " ", "\t" '無視するキーワード
Case Else '演算する文字列
wrd += tmp
End Select
End While
If wrd <> "" Then stk.Push(Decoder(wrd))
If hugo <> "" Then enzan(hugo)
While 0 < R1.Count : enzan(R1.Pop()) : End While
End Sub
Private Sub enzan(ByVal data As String)
Dim R As Integer = stk.Pop()
Dim L As Integer = stk.Pop()
Select Case data
Case "+" : stk.Push(L + R)
Case "-" : stk.Push(L - R)
Case "*" : stk.Push(L * R)
Case "/" : stk.Push(L \ R)
End Select
End Sub
Private Function Decoder(ByVal data As String) As Integer
Dim ret As Integer = 0
If Int32.TryParse(data, ret) Then Return ret
Return param(data)
End Function
End Module
どっちがいいかは不明。
2013年1月23日水曜日
.NET 軽量ORマッパー
.NETでORマッパー関連が充実していなくて困った。
.NET標準のADO.net Entity frameworkを使えばモデリングからある程度自動生成してくれるが、
pythonのdjangoのORマッパーを味わってしまうとめんどくさい。。
Ironpythonを使って、メイン言語をPythonにして画面だけWPFにしようとも考えたけど、これもめんどくさい。。
MySQLなど大規模なファイルでない、ちょっとしたパラメータをファイルに保存しておきたいだけなのに、どうしたものか。
探しても無いから自分でJson形式なORマッパーを作ってみた。
仕様は、
・データ保存形式は、 jsonを使用。
・ORマッパーでModelクラス経由でアクセス。
・検索機能は、Linqを使う。
これだけで十分と思う人向け。
Imports Newtonsoft.Json.Linq
Imports Newtonsoft.Json
Imports System.ComponentModel
Imports System.IO
Public Class BookModel
<displayname("書籍名")>
Public Property Name As String = ""
<displayname("バーコード")>
Public Property BCode As String = ""
<displayname("ページ数")>
Public Property Pages As Integer = 0
<displayname("価格")>
Public Property Price As Integer = 0
Public Sub New(ByVal name As String, ByVal bcode As String, ByVal pages As Integer, ByVal price As Integer)
With Me
.Name = name
.BCode = bcode
.Pages = pages
.Price = price
End With
End Sub
End Class
Class BookCollection : Implements IListSource
Public Property models As New List(Of BookModel)
#Region "IListSource"
Private bindsrc As New BindingSource
Public ReadOnly Property ContainsListCollection As Boolean Implements IListSource.ContainsListCollection
Get
Return False
End Get
End Property
Public Function GetList() As IList Implements IListSource.GetList
bindsrc.DataSource = models
Return bindsrc
End Function
#End Region
#Region "ファイル操作"
Public Sub Save(ByVal fname As String)
Dim json As String = JsonConvert.SerializeObject(models)
File.WriteAllText(fname, json)
End Sub
Public Sub Load(ByVal fname As String, typ As Type)
Dim json As String = File.ReadAllText(fname)
json = json.Replace(vbTab, "").Replace("\", "\\")
models = JsonConvert.DeserializeObject(Of List(Of BookModel))(json)
bindsrc.ResetBindings(False)
End Sub
#End Region
End Class
使い方例:
'データ定義
Dim bc As New BookCollection()
bc.models.Add(New BookModel("書籍1", "4987185712345", 100, 100))
bc.models.Add(New BookModel("書籍2", "4987185712346", 110, 200))
bc.models.Add(New BookModel("書籍3", "4987185712347", 120, 300))
'保尊
co.Save("d:\test.json")
'読込
co.Load("d:\test.json", rack.GetType())
'条件検索
Dim filter = From x In bc.models Where x.Price >= 200 Select x
For Each model As BookModel In filter
Console.WriteLine(model.Name)
Next
'DataGridViewで表示する
DataGridView1.DataSource = co.models
DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
DataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
機能拡張など、こうしたら良いなどアイデアがあれば教えてください。
2013年1月21日月曜日
つるとんたん新宿店
つるとんたん
http://www.tsurutontan.co.jp/
坂本龍の番組だったか
カトープレジャー グループの社長が出演していた回の放送をみて知ったお店である。
番組内で「わざわざ来てくれるお店」を作るのがやり方のようで、
どんなお店か行ってみた。
行ってきた場所は、つるとんたん新宿店。
歌舞伎町方面、元コマ劇場があった所から1本奥の通りを右方向に進むと、地下1階にお店があった。
内装はまるで、キャバクラをうどん店へ改装した感じの作りになっていて、
カウンター席は、ディズニーのホンデットマンションの椅子みたいなでっかい椅子で二人が座れる席。
テーブル席もいくつかあるが、席に座ってる人達を見てみると器が通常の2倍サイズくらいあって迫力満点。
15時頃に入ったときは空いていたのか、20分くらい待って、さっそく案内されて注文したのはコレ。
釜揚げうどん。これにアナゴとネギトロ丼を頼んでみた。
注文した時に聞いたのだが、替え玉が3回まで無料でOKみたい。
さっそく食べてみた感想。
麺はつるつるで太麺の讃岐うどん。
味はシンプルかなー。一緒に行った人のも食べてみたけど同じ感想。
でもお店の内装や器、いろんな所は他のうどん屋に無いね。かなり個性的。
夜はライブもやるみたいなので、行列間違いなしだと思う。
個人的にうどんなら三国一!
http://www.tsurutontan.co.jp/
坂本龍の番組だったか
カトープレジャー グループの社長が出演していた回の放送をみて知ったお店である。
番組内で「わざわざ来てくれるお店」を作るのがやり方のようで、
どんなお店か行ってみた。
行ってきた場所は、つるとんたん新宿店。
歌舞伎町方面、元コマ劇場があった所から1本奥の通りを右方向に進むと、地下1階にお店があった。
内装はまるで、キャバクラをうどん店へ改装した感じの作りになっていて、
カウンター席は、ディズニーのホンデットマンションの椅子みたいなでっかい椅子で二人が座れる席。
テーブル席もいくつかあるが、席に座ってる人達を見てみると器が通常の2倍サイズくらいあって迫力満点。
15時頃に入ったときは空いていたのか、20分くらい待って、さっそく案内されて注文したのはコレ。
釜揚げうどん。これにアナゴとネギトロ丼を頼んでみた。
注文した時に聞いたのだが、替え玉が3回まで無料でOKみたい。
さっそく食べてみた感想。
麺はつるつるで太麺の讃岐うどん。
味はシンプルかなー。一緒に行った人のも食べてみたけど同じ感想。
でもお店の内装や器、いろんな所は他のうどん屋に無いね。かなり個性的。
夜はライブもやるみたいなので、行列間違いなしだと思う。
個人的にうどんなら三国一!
C#とipythonでDjango
VS2012 Professional版使っていれば、PTVSをインストール、
VS2012 express版でも別途shellをインストールすれば済む話じゃないかっという話だけど、
今回は自力でやってみる方法を選んでみた。
1.インストール
ironpython、easy_installなど必要なものを順次インストールしていく。
IronPython
http://ironpython.codeplex.com/easy_setup
http://peak.telecommunity.com/dist/ez_setup.py
2.環境変数に下記のパスを追加。
Path
C:\Program Files (x86)\IronPython 2.7\
C:\Program Files (x86)\IronPython 2.7\Scripts\
C:\Program Files (x86)\IronPython 2.7\Lib\
C:\Program Files (x86)\IronPython 2.7\Lib\site-packages\
PythonHome
C:\Program Files (x86)\IronPython 2.7\
3.モジュールを入れる。
ipy64 Scripts\easy_install sqlite ipy64 Scripts\easy_install django
4.このままだとunicodeエラーが発生するので、djangoにパッチをあてる。 https://bitbucket.org/jdhardy/django-ironpython/commits/b70eeacda60c
.\lib\site-packages\django-1.4.3-py2.7.egg\django\utils\funcional
---95行目付近
- assert not (cls._delegate_str and cls._delegate_unicode), "Cannot call lazy() with both str and unicode return types."
+ assert (str is unicode) or not (cls._delegate_str and cls._delegate_unicode), "Cannot call lazy() with both str and unicode return types."
---
5.プロジェクト作成
ipy64 -X:FullFrames Scripts\django-admin.py startproject project_name
ipy64の引数「-X:FullFrames」これが入ってなくて一度つまづいた所である。
詳しくはipy64 -hで参照すること。
VS2012 express版でも別途shellをインストールすれば済む話じゃないかっという話だけど、
今回は自力でやってみる方法を選んでみた。
1.インストール
ironpython、easy_installなど必要なものを順次インストールしていく。
IronPython
http://ironpython.codeplex.com/easy_setup
http://peak.telecommunity.com/dist/ez_setup.py
2.環境変数に下記のパスを追加。
Path
C:\Program Files (x86)\IronPython 2.7\
C:\Program Files (x86)\IronPython 2.7\Scripts\
C:\Program Files (x86)\IronPython 2.7\Lib\
C:\Program Files (x86)\IronPython 2.7\Lib\site-packages\
PythonHome
C:\Program Files (x86)\IronPython 2.7\
3.モジュールを入れる。
ipy64 Scripts\easy_install sqlite ipy64 Scripts\easy_install django
4.このままだとunicodeエラーが発生するので、djangoにパッチをあてる。 https://bitbucket.org/jdhardy/django-ironpython/commits/b70eeacda60c
.\lib\site-packages\django-1.4.3-py2.7.egg\django\utils\funcional
---95行目付近
- assert not (cls._delegate_str and cls._delegate_unicode), "Cannot call lazy() with both str and unicode return types."
+ assert (str is unicode) or not (cls._delegate_str and cls._delegate_unicode), "Cannot call lazy() with both str and unicode return types."
---
5.プロジェクト作成
ipy64 -X:FullFrames Scripts\django-admin.py startproject project_name
ipy64の引数「-X:FullFrames」これが入ってなくて一度つまづいた所である。
詳しくはipy64 -hで参照すること。
2012年12月28日金曜日
Raspberry Piが届いた
今までMini2440を扱ってきたけど、今度は液晶パネル無しのRaspberry PiをRSコンポーネント経由で購入してみた。
部品不足らしく、注文してから2ヶ月ほど掛かるので、注文する方は直ぐには届かないと思っておいた方がいいと思います。
詳細スペック
http://ja.wikipedia.org/wiki/Raspberry_Pi
さっそく箱を開けてみると、名刺サイズの基板が入っていた。
700MHzのCPUと512MBのメモリーとGPIOにUSB、LANなどもついて3500円。
自分で基板を作ってやるよりも安くできそうだが、SDカードからブートになるため、起動時間はNANDフラッシュで起動可能なMINI2440と比べて遅くなる上、カードを抜き取られると中身が全て丸見えになるので、セキュリティー面で難あり。
だが基板単体で遊ぶには値段も手ごろでよさそうだ。
明後日から年末休みになるので、debianのインストールや無線LANを使って色々やってみようと思う。
部品不足らしく、注文してから2ヶ月ほど掛かるので、注文する方は直ぐには届かないと思っておいた方がいいと思います。
詳細スペック
http://ja.wikipedia.org/wiki/Raspberry_Pi
さっそく箱を開けてみると、名刺サイズの基板が入っていた。
700MHzのCPUと512MBのメモリーとGPIOにUSB、LANなどもついて3500円。
自分で基板を作ってやるよりも安くできそうだが、SDカードからブートになるため、起動時間はNANDフラッシュで起動可能なMINI2440と比べて遅くなる上、カードを抜き取られると中身が全て丸見えになるので、セキュリティー面で難あり。
だが基板単体で遊ぶには値段も手ごろでよさそうだ。
明後日から年末休みになるので、debianのインストールや無線LANを使って色々やってみようと思う。
ラベル:
Raspberry_Pi
2012年9月19日水曜日
djangoでjsonpを返す
クロスドメインでjsonデータのやり取りするアプリを開発していた時に
ブラウザからアクセスするとちゃんと返ってくるのに、
「$.getJSON」や「$.ajax」を使うとHTTPレスポンス200なのにエラーが返ってくる現象に出くわした。
しばらく悩んでたらajaxのポリシーでクロスドメインにアクセスするときはjsonpを使う必要があるようだった。
どういったものなのかというと、通常はjsonそのまま渡すのに対して、
jsonpは、queryに書かれたcallback名で囲ってapplication/javascriptで返すようになる。
実装方法は下にまとめてみた。
まずはjavascript側から
次にサーバ側(django)もjsonpに対応
ブラウザからアクセスするとちゃんと返ってくるのに、
「$.getJSON」や「$.ajax」を使うとHTTPレスポンス200なのにエラーが返ってくる現象に出くわした。
しばらく悩んでたらajaxのポリシーでクロスドメインにアクセスするときはjsonpを使う必要があるようだった。
どういったものなのかというと、通常はjsonそのまま渡すのに対して、
jsonpは、queryに書かれたcallback名で囲ってapplication/javascriptで返すようになる。
jsonの場合
http://127.0.0.1/sample/
{data1:1, data2:"hello"}
jsonpの場合
http://127.0.0.1/sample/?callback=jsonp_1234&_=2345
jsonp_12345({data1:1, data2:"hello"});
実装方法は下にまとめてみた。
まずはjavascript側から
$.getJSON('http://127.0.0.1/sample/?callback=?', function(data){console.dir(data);});
$.ajax({url:'http://127.0.0.1/sample/', dataType='jsonp', success: function(data){console.dir(data);});
次にサーバ側(django)もjsonpに対応
def JSONP(f):
"""
Usage:
@JSONP
def func(request):
dic = { 'data1': 1, 'data2': 'hello'}
return dic
"""
def _func(*args, **kwargs):
request = args[0]
callback = request.GET.get('callback', None)
dic = f(request)
ret = json.dumps(dic)
if callback is None:
ct = 'application/json'
else:
ret = '%s(%s);' % (callback, ret)
ct = 'application/javascript'
return HttpResponse(ret, mimetype=ct)
return _func
ラベル:
django
2012年9月14日金曜日
jquery mobile + backbone サンプル(2)
前回の続き。
今回はViewにイベントを追加してみる。
一応Viewのおさらいをしておくと、View=画面になる。
画面にはボタンなどが配置されていて、 マウスやタッチパネルで操作ができ、ユーザからイベント発行される。
今回はそのボタンとイベントを作成してみようと思う。
前回のソースから、テンプレートにボタンを配置して、ボタンが押されたらカウンターが+1されるようにした。
ボタンID = btn_push
イベントID=evt_push
1つ注意しておいてほしいのが、render内にタグを書き換えた後にtriggerでcreateしている所。
これを行わないとjquery mobileのボタン装飾などがされなくなるので入れておく必要がある。
関連記事
jquery mobile + backbone サンプル(1)
今回はViewにイベントを追加してみる。
一応Viewのおさらいをしておくと、View=画面になる。
画面にはボタンなどが配置されていて、 マウスやタッチパネルで操作ができ、ユーザからイベント発行される。
今回はそのボタンとイベントを作成してみようと思う。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>example</title>
<link rel="stylesheet" href="./jquery.mobile-1.1.1/jquery.mobile-1.1.1.min.css" />
<link rel="stylesheet" href="my.css" />
<style>
</style>
<script src="underscore.js"></script>
<script src="json2.js"></script>
<script src="jquery-1.7.1.min.js"></script>
<script src="backbone-min.js"></script>
<script src="./jquery.mobile-1.1.1/jquery.mobile-1.1.1.min.js"></script>
<script src="my.js"></script>
</head>
<body>
<div data-role="page" id="page1">
<div data-theme="a" data-role="header"><h3>sample2</h3></div>
<div data-role="content" style="padding: 15px">
<!-- content start -->
<div id="myview"></div>
<!-- content end -->
</div>
<div data-theme="a" data-role="footer" data-position="fixed"><h3></h3></div>
</div>
<!-- underscore template start -->
<script type="text/template" id="hello-template">
<button id="btn_push">Push</button>
<h3><%= part1 %>, <%= part2 %>!</h3>
<h3>counter <%= counter %></h3>
</script>
<!-- underscore template end -->
<!-- backbone start -->
<script>
(function($){
MyView = Backbone.View.extend({
el: '#myview'
,initialize: function(){
this.counter = 0;
this.render();
}
,render: function(){
var data = { part1: 'hello', part2: 'backbone!', counter: this.counter }
var tmpl = _.template($("#hello-template").html(), data);
this.$el.html(tmpl);
this.$el.trigger('create');
}
,events: {
'click button#btn_push': 'evt_push'
}
,evt_push: function(){
this.counter++;
this.render();
}
});
var myview = new MyView();
})(jQuery);
</script>
<!-- backbone end -->
</body>
</html>
前回のソースから、テンプレートにボタンを配置して、ボタンが押されたらカウンターが+1されるようにした。
ボタンID = btn_push
イベントID=evt_push
1つ注意しておいてほしいのが、render内にタグを書き換えた後にtriggerでcreateしている所。
これを行わないとjquery mobileのボタン装飾などがされなくなるので入れておく必要がある。
関連記事
jquery mobile + backbone サンプル(1)
ラベル:
backborn,
jquery mobile
2012年9月13日木曜日
jquery mobile + backbone サンプル(1)
jquery mobileを使っていろんな情報を見て覚えて使ってみて、やっぱまともじゃない。jqmは使えない!って何度も思ったことか。ほんとWeb周りの技術ってごちゃごちゃしてて苦難の道のりである。
というわけで行き着いた先はbackbone.jsであった。
チュートリアルを見てもちんぷんかんぷんで、なんじゃこりゃー!と思いつつ1つ1つ解いていくことにする。
Backbone.JSって何?
Javascriptで書かれているMVCフレームワークである。
フレームワークの構成はRouter、Model、Collect、Viewの4構成で出来ている。
各々の説明すると、
・ページ単位で切り分けるRouter、
・データ定義するModel 、
・複数のデータを管理するCollect、
・画面周りを担当するView
という感じになる。
次にフレームワークの基本的な流れ。
ページアクセス
↓
Routerで振り分け
↓
Viewでページ作成
↓
Collect、Model必要なデータを引っ張ってくる。
↓
画面表示
MVCフレームワークを使った事がある人であれば馴染みやすいと思う。
またこの他に、
HTMLを吐き出すテンプレート「underscore」
画面のデコレーション担当「jquery mobile」
があって今回のサンプルプログラムで使ったコードを張っておく。
ここまで頭の中を文章に吐き出してみた。
あとは使って覚えて知識の補強を繰り返していけば、実用投入ができるかもしれない。
ちなみに、このbackbone.jsは軽量って謳ってるけど、軽量という言葉は最近の流行なのだろうか。
体重100kg軽量級とか軽量ってタイトルが付くと、一瞬だけ軽そうって気分になるけど。
準備するもの
jQuery mobile + backboneするのに今回は以下のライブラリを用意する。
http://jquery.com/http://documentcloud.github.com/underscore/
https://github.com/douglascrockford/JSON-js
http://backbonejs.org/
http://jquerymobile.com/
いよいよ Hello, Bavkbone! を書く
ベースのHTMLコードはjquery mobile サイトのデザイナツールで作りました。
それに加えてbackboneのViewとunderscoreを今回使用してます。
簡単に解説
タグで囲った部分が3ブロック構成、コンテンツ、テンプレート、backboneで出来てます。 上から、
1.コンテンツ部分。
動的にしたい部分divタグにidを付けたものを挿入します。
2.テンプレート部分。
動的に表示させるHTMLをunderscoreの記述にしたがって記述します。
3.Backbone部分
どういったデータを加工して表示させるのかを記述します。
・elが対応する1のdivタグのID
・Viewの定義、initializeと、renderを記述。
動作の説明
できたら最後にビューのインスタンスを作成して終えてます。
これをやるとどうなるかというと、 Myviewのinitialize()が呼び出されてrender()を呼ぶ。
render()内で今回用意したデータとテンプレートを使ってHTMLを作って、 elにデータセットして終えてます。
最初に説明したフローで説明すると、
ページアクセス
↓
Routerで振り分け (スキップ)
↓
Viewでページ作成
↓
Collect、Model必要なデータを引っ張ってくる。 (スキップ)
↓
画面表示
だいぶ省略してますが、backboneのViewとテンプレートを使ったHTMLレンダリングの仕組みが見えてくると思う。
- jquery mobileをそのまま使ってみると、ページ遷移やajax周りで泣く。(過去記事参照)
- なんとか普通に動くようになったからコード整理しようと思いテンプレートエンジンの導入を考える。
- angularJSを使ってみるとjqmと相性が悪くて使えない。angularJS-jquery-adapterなるものを使ってみる。
- イベント周りとかテンプレートが強力でほんとjqmバイパス感が強いけど使えるんだけど、adapter側の情報が少ないし、画面遷移周りでフリーズすることもあり次を探しに出る。
- クライアントサイド側のMVCフレームワークで一番情報が豊富と書かれていたbackbone.jsに手を出してみる。←今ココ!
というわけで行き着いた先はbackbone.jsであった。
チュートリアルを見てもちんぷんかんぷんで、なんじゃこりゃー!と思いつつ1つ1つ解いていくことにする。
Backbone.JSって何?
Javascriptで書かれているMVCフレームワークである。
フレームワークの構成はRouter、Model、Collect、Viewの4構成で出来ている。
各々の説明すると、
・ページ単位で切り分けるRouter、
・データ定義するModel 、
・複数のデータを管理するCollect、
・画面周りを担当するView
という感じになる。
次にフレームワークの基本的な流れ。
ページアクセス
↓
Routerで振り分け
↓
Viewでページ作成
↓
Collect、Model必要なデータを引っ張ってくる。
↓
画面表示
MVCフレームワークを使った事がある人であれば馴染みやすいと思う。
またこの他に、
HTMLを吐き出すテンプレート「underscore」
画面のデコレーション担当「jquery mobile」
があって今回のサンプルプログラムで使ったコードを張っておく。
ここまで頭の中を文章に吐き出してみた。
あとは使って覚えて知識の補強を繰り返していけば、実用投入ができるかもしれない。
ちなみに、このbackbone.jsは軽量って謳ってるけど、軽量という言葉は最近の流行なのだろうか。
体重100kg軽量級とか軽量ってタイトルが付くと、一瞬だけ軽そうって気分になるけど。
準備するもの
jQuery mobile + backboneするのに今回は以下のライブラリを用意する。
http://jquery.com/http://documentcloud.github.com/underscore/
https://github.com/douglascrockford/JSON-js
http://backbonejs.org/
http://jquerymobile.com/
いよいよ Hello, Bavkbone! を書く
ベースのHTMLコードはjquery mobile サイトのデザイナツールで作りました。
それに加えてbackboneのViewとunderscoreを今回使用してます。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>example</title>
<link rel="stylesheet" href="./jquery.mobile-1.1.1/jquery.mobile-1.1.1.min.css" />
<link rel="stylesheet" href="my.css" />
<style>
</style>
<script src="underscore.js"></script>
<script src="json2.js"></script>
<script src="jquery-1.7.1.min.js"></script>
<script src="backbone-min.js"></script>
<script src="./jquery.mobile-1.1.1/jquery.mobile-1.1.1.min.js"></script>
<script src="my.js"></script>
</head>
<body>
<div data-role="page" id="page1">
<div data-theme="a" data-role="header"><h3>sample1</h3></div>
<div data-role="content" style="padding: 15px">
<!-- content start -->
<div id="myview"></div>
<!-- content end -->
</div>
<div data-theme="a" data-role="footer" data-position="fixed"><h3></h3></div>
</div>
<!-- underscore template start -->
<script type="text/template" id="hello-template">
<h3><%= part1 %>, <%= part2 %>!</h3>
</script>
<!-- underscore template end -->
<!-- backbone start -->
<script>
MyView = Backbone.View.extend({
el: '#myview'
,initialize: function(){
this.render();
}
,render: function(){
var data = { part1: 'hello', part2: 'backbone!' }
var tmpl = _.template($("#hello-template").html(), data);
this.$el.html(tmpl);
}
});
var myview = new MyView();
<!-- backbone end -->
</script>
</body>
</html>
簡単に解説
タグで囲った部分が3ブロック構成、コンテンツ、テンプレート、backboneで出来てます。 上から、
1.コンテンツ部分。
動的にしたい部分divタグにidを付けたものを挿入します。
2.テンプレート部分。
動的に表示させるHTMLをunderscoreの記述にしたがって記述します。
3.Backbone部分
どういったデータを加工して表示させるのかを記述します。
・elが対応する1のdivタグのID
・Viewの定義、initializeと、renderを記述。
動作の説明
実行画面
できたら最後にビューのインスタンスを作成して終えてます。
これをやるとどうなるかというと、 Myviewのinitialize()が呼び出されてrender()を呼ぶ。
render()内で今回用意したデータとテンプレートを使ってHTMLを作って、 elにデータセットして終えてます。
最初に説明したフローで説明すると、
ページアクセス
↓
↓
Viewでページ作成
↓
↓
画面表示
だいぶ省略してますが、backboneのViewとテンプレートを使ったHTMLレンダリングの仕組みが見えてくると思う。
ラベル:
backborn,
jquery mobile
2012年9月10日月曜日
jquery mobile のページ切り替えの挙動(イラッ
とにかくajaxの挙動がおかしい!それでも使いたい!って方用にメモを残しておく。
ページ切替イベントに
http://dev.screw-axis.com/doc/jquery_mobile/api/events/page_transition/about/
pagebeforehide
pagebeforeshow
pagehide
pageshow
の4つがあると記載してあるけど、実はもう一つあって
ページ遷移先のdiv[data-role="page"]タグ内にある<script>タグがある。
scriptタグはページを読込んだ直後に実行されるので、
pagebeforchangeよりも早く実行される。
data-prefetchした場合は裏でajax通信した時に読込む。
これが一番の問題。
どういうことかというと、ページ切替前にscriptが解釈されてしまうので、
当然ページ切替後に反映される事はない。
リロードしたときはうまくいくのに、ページ移動だとうまく行かないっていうのは
ここが原因となっているので、
ウェジット回りのイベント処理などは、素直に
jquery mobileでイベント処理をやらない
これが対策。
jquery mobileでイベント処理をやらない
がとても重要。
具体的には、
1.ページ切替などそういった処理はヘッダー内scriptに記述して、できるだけ
処理を入れないようにする。
2.ウェジット回りのイベントはhtml内のdiv[page]内scriptタグで記述して、
onclickタグやonchangeタグを使って呼び出すようにする。
これだけ制約すれば素直に動いてくれるはず。
ページ切替イベントに
http://dev.screw-axis.com/doc/jquery_mobile/api/events/page_transition/about/
pagebeforehide
pagebeforeshow
pagehide
pageshow
の4つがあると記載してあるけど、実はもう一つあって
ページ遷移先のdiv[data-role="page"]タグ内にある<script>タグがある。
scriptタグはページを読込んだ直後に実行されるので、
pagebeforchangeよりも早く実行される。
data-prefetchした場合は裏でajax通信した時に読込む。
これが一番の問題。
どういうことかというと、ページ切替前にscriptが解釈されてしまうので、
当然ページ切替後に反映される事はない。
リロードしたときはうまくいくのに、ページ移動だとうまく行かないっていうのは
ここが原因となっているので、
ウェジット回りのイベント処理などは、素直に
jquery mobileでイベント処理をやらない
これが対策。
jquery mobileでイベント処理をやらない
がとても重要。
具体的には、
1.ページ切替などそういった処理はヘッダー内scriptに記述して、できるだけ
処理を入れないようにする。
2.ウェジット回りのイベントはhtml内のdiv[page]内scriptタグで記述して、
onclickタグやonchangeタグを使って呼び出すようにする。
これだけ制約すれば素直に動いてくれるはず。
ラベル:
jquery
2012年9月7日金曜日
jquery mobileの悪い所
ajaxをONにしてうまく使えないか試行錯誤してたらべからず集ができそうなくらい問題が出てきた。
・DOMキャッシュ機能をPOST先のページがおかしくなる。
・location.hrefだと履歴やハッシュが付かなくなって次表示するとき更新されない。
・ときどきページが巻き戻る。
・ときどきGUIが素の状態になる。
・ときどきscriptタグ内の処理がスキップする。
・ときどきブラウザがフリーズする。
・WEBアプリ側でリダイレクトするとものアウト。
・リダイレクトしちゃった場合はcontent内に正式なURLを埋め込まないとリダイレクト前のURLになる。
・contentタグ内のページ名はユニークにしないとだめ。
・ラジオボタンをクリックしたときとかchangepageでページ遷移できない。
こんだけ問題に直面すると時間がいくらあっても足りないしストレスとカフェインの量が増えてくる。
.NETとかがものすごく洗練された開発環境だなあと思えてきた。
・DOMキャッシュ機能をPOST先のページがおかしくなる。
・location.hrefだと履歴やハッシュが付かなくなって次表示するとき更新されない。
・ときどきページが巻き戻る。
・ときどきGUIが素の状態になる。
・ときどきscriptタグ内の処理がスキップする。
・ときどきブラウザがフリーズする。
・WEBアプリ側でリダイレクトするとものアウト。
・リダイレクトしちゃった場合はcontent内に正式なURLを埋め込まないとリダイレクト前のURLになる。
・contentタグ内のページ名はユニークにしないとだめ。
・ラジオボタンをクリックしたときとかchangepageでページ遷移できない。
こんだけ問題に直面すると時間がいくらあっても足りないしストレスとカフェインの量が増えてくる。
.NETとかがものすごく洗練された開発環境だなあと思えてきた。
ラベル:
jquery
2012年9月5日水曜日
jquery mobileでajaxを使う。
右も左も知らないまま、jquery mobileを使ってajax通信を使って動的なページを作ろうと思ったときに陥った罠を紹介。
今日の問題テーマ
1.pageinitでsetIntervalを使って定期的にajax通信を行う仕組みを入れると、ページ切り替えた後もajax通信を行っている。
2.ページ遷移先のjavascript(pageinit部分)が処理されない。
3.jquery mobile側のページ遷移で使われてるajaxをoffにすれば解決してしまう。(悪くないがせっかくなので使いたい)
4.ページ内でajaxを使うと時々エラーが発生する。
これくらいの内容を紹介。
ここからたんたんと書いておく。
jquery mobileとは
基本的な部品とページ遷移するときのアニメーションなどを提供してくれるライブラリでバックエンドにはajaxが使われている。ajaxをオフにするとページ遷移時のアニメーションがしなくなるなどの制限が付く。 あと、jquery mobileを使って自分でもajax通信するときは、多重通信するとエラーが起きるのでそのへんの制御を作りこまないといけないし、ページ遷移前には通信してない状態にもっていかないとだめである。 イベントフック自体はjquery mobileに提供されているものを使うことがリファレンスでも書かれているので目を当しておくこと。
jquery mobileがajaxONだとどうなるの?
最初に開いたページがベースとなるので、ヘッダ、ボディー共に読み込まれる。ページ遷移はajax通信でリンク先のページデータを読み込んで、ヘッダタグはスキップしてボディータグ内にある
自分でもajax使う実装はどうやるの?
ページ遷移先のDivタグ内にscriptタグを仕込んでおいてそこに自分でajax通信をするプログラムを書いてあげればよい。Divタグ内で完結するscriptタグなので、グローバル変数が他ページとかぶっても置き換わる事もないし、引き継がれない。もしグローバル変数を使うならdivタグで囲まれたページタグ以外のエリアにメモしておけばいいと思う。もし、定期タイマーでajax通信する場合は、pageshow、pagehideでタイマーのON/OFF制御してあげればアクティブなときだけ通信するようになる。ちなみにjquery mobile公式ページにある画面レイアウト作成できるのでソースをエクスポートした場合、scriptタグがdivタグの外側にはみ出してるので厳重に注意しておくこと。
ここまでで1~4の解決策は書けた。
最後に、jquery標準のreadyじゃなくpageinitを使え!ってリファレンスに書かれてるからどこの記事でもpageinitで解決って感じに書かれているけど著者の意図通りに使われてないケースをよく見かける。
そもそもpageinitを使うケースは共通の初期化を行う時くらいなもんだろう。delegateとかするときはinitで、より使うほうはページ切り替え時の処理がメインなんじゃないかなと思う。でもまあ、このあたりは必要とされる技術を適材適所に使っていればいいので、どういうイベントがあるのかは頭の隅にでも覚えておくと良いと思います。
あとは全体の実装方法なんだけど、すっきりしたやり方がまだまとまってないので今日はここまで。
今日の問題テーマ
1.pageinitでsetIntervalを使って定期的にajax通信を行う仕組みを入れると、ページ切り替えた後もajax通信を行っている。
2.ページ遷移先のjavascript(pageinit部分)が処理されない。
3.jquery mobile側のページ遷移で使われてるajaxをoffにすれば解決してしまう。(悪くないがせっかくなので使いたい)
4.ページ内でajaxを使うと時々エラーが発生する。
これくらいの内容を紹介。
ここからたんたんと書いておく。
jquery mobileとは
基本的な部品とページ遷移するときのアニメーションなどを提供してくれるライブラリでバックエンドにはajaxが使われている。ajaxをオフにするとページ遷移時のアニメーションがしなくなるなどの制限が付く。 あと、jquery mobileを使って自分でもajax通信するときは、多重通信するとエラーが起きるのでそのへんの制御を作りこまないといけないし、ページ遷移前には通信してない状態にもっていかないとだめである。 イベントフック自体はjquery mobileに提供されているものを使うことがリファレンスでも書かれているので目を当しておくこと。
jquery mobileがajaxONだとどうなるの?
最初に開いたページがベースとなるので、ヘッダ、ボディー共に読み込まれる。ページ遷移はajax通信でリンク先のページデータを読み込んで、ヘッダタグはスキップしてボディータグ内にある
タグで囲まれたページを読み込んで、ページを書き換えるついでにアニメーションをはさむようになる。OFFにした場合は通常のページ移動するのでページ遷移先のヘッダーとボディーを再度読み込む。
自分でもajax使う実装はどうやるの?
ページ遷移先のDivタグ内にscriptタグを仕込んでおいてそこに自分でajax通信をするプログラムを書いてあげればよい。Divタグ内で完結するscriptタグなので、グローバル変数が他ページとかぶっても置き換わる事もないし、引き継がれない。もしグローバル変数を使うならdivタグで囲まれたページタグ以外のエリアにメモしておけばいいと思う。もし、定期タイマーでajax通信する場合は、pageshow、pagehideでタイマーのON/OFF制御してあげればアクティブなときだけ通信するようになる。ちなみにjquery mobile公式ページにある画面レイアウト作成できるのでソースをエクスポートした場合、scriptタグがdivタグの外側にはみ出してるので厳重に注意しておくこと。
ここまでで1~4の解決策は書けた。
最後に、jquery標準のreadyじゃなくpageinitを使え!ってリファレンスに書かれてるからどこの記事でもpageinitで解決って感じに書かれているけど著者の意図通りに使われてないケースをよく見かける。
そもそもpageinitを使うケースは共通の初期化を行う時くらいなもんだろう。delegateとかするときはinitで、より使うほうはページ切り替え時の処理がメインなんじゃないかなと思う。でもまあ、このあたりは必要とされる技術を適材適所に使っていればいいので、どういうイベントがあるのかは頭の隅にでも覚えておくと良いと思います。
あとは全体の実装方法なんだけど、すっきりしたやり方がまだまとまってないので今日はここまで。
ラベル:
jquery
2012年8月31日金曜日
jquery mobileでpageinitするときの注意点
見事にはまった。
jquery自体始めて使うので、右も左も分からない事もあるんだけども
ドキュメント通りにコピペしてもpageinitは動かない!という問題にずっぽりはまってしまった。
色々足掻いてたら解決したのでメモっておく。
まずjquery mobileは通常ajaxがONになっていて、ページ切り替え時は
ajaxで次のページを読込んでからアニメーションして画面が切り替わる仕組みになっている。
こいつが動いてると初めに読込んだscript以外は読込まない挙動っぽい。
つまり対策方法は、
・どのページでもヘッダーに共通のスクリプトを読込むようにしておき、スクリプト内に画面の設定を記述しておく。
・ページ切り替えるタグにパラメータで「data-ajax="false"」を付け加えておく。
この2つに絞られる。
前者のがページ切り替わる時のアニメーションが付いてお手ごろなのだが
ページ数が多くなると厄介なので、今のところはsubmitやタグのところに後者のdata-ajax=falseを入れて対応しておいた。
jquery自体始めて使うので、右も左も分からない事もあるんだけども
ドキュメント通りにコピペしてもpageinitは動かない!という問題にずっぽりはまってしまった。
色々足掻いてたら解決したのでメモっておく。
まずjquery mobileは通常ajaxがONになっていて、ページ切り替え時は
ajaxで次のページを読込んでからアニメーションして画面が切り替わる仕組みになっている。
こいつが動いてると初めに読込んだscript以外は読込まない挙動っぽい。
つまり対策方法は、
・どのページでもヘッダーに共通のスクリプトを読込むようにしておき、スクリプト内に画面の設定を記述しておく。
・ページ切り替えるタグにパラメータで「data-ajax="false"」を付け加えておく。
この2つに絞られる。
前者のがページ切り替わる時のアニメーションが付いてお手ごろなのだが
ページ数が多くなると厄介なので、今のところはsubmitやタグのところに後者のdata-ajax=falseを入れて対応しておいた。
ラベル:
jquery
登録:
投稿 (Atom)





