MoyaSystem

もやしです。

Alloyで画面間の変数の引き渡しにハマって、結局解決してない話

タイトルが残念なのはいつもどおりです。

そもそも

Titanium Mobile でスマホアプリの開発をしていて、画面間で値の引き渡しをしたいな、と思っていたのです。

window1.js

var myVar = $.myInputField.value;
var window2 = Alloy.createController('window2', {
    myVar: myVar
}).getView();
window2.open();

画面間で値を引き渡したいときは、createControllerの第2引数にオブジェクトを指定すれば良いですね。

window2はふたつのタブを持っていて、こんな感じです。

window2.xml

<Alloy>
	<TabGroup id="mainTabGroup">
		<Tab id="tab1">
			<Require type="view" src="window3" id="window3Tab">
		</Tab>
		<Tab id="tab2">
			<Require type="view" src="subdir/window4" id="window4Tab">
		</Tab>
	</TabGroup>
</Alloy>

windows2.js

var args = arguments[0] || {};
var myVar = args.myVar;
var window4 = Alloy.createController('window4', {
    myVar: myVar
});

window4.js

var args = arguments[0] || {};
var myVar = args.myVar;
Ti.API.info('myVar in window4 is' + myVar);

function callbackFunction(){
    Ti.API.info('myVar in callbackFunction is' + myVar);
    alert(myVar); // ここでmyVarを使いたい
}

とまぁ、こう書けばいいだろうと思ってました。
ところがこれで実行すると、window4のalertでmyVarの値が空になっている!
おかしいなーと思ってコンソールを見ると、

myVar in window4 is
myVar in window4 is myInputFieldValue
myVar in callbackFunction is

え?window4の初期化処理が2回走ってる?

そしてよくよく調査してみると、window1でcreateControllerを読んだ瞬間に1回目の初期化処理が走っているのです。
その後window2でまたcreateControllerが呼ばれますが、最終的に実行されるのは1回めに初期化されたwindow4。
ということは、このやりかたではwindow4にmyVarを引き渡すことができない……どうすればよいのだ……。

で、結局

いろいろ試しましたがうまくいかず、直接値を引き渡すのは諦めて、window1の時点でファイルに書き出してwindow4でファイル読み込みするという方式に変えました。どうにも悔しいですがしょうがない……。