3

Titanium を使用して iOS アプリを作成しています。tableView にアルファベット順のリストを表示しようとしています。特定の行が選択されたときに、行情報を新しいウィンドウに渡したい。私が持っているコードは、リストをヘッダー付きのグループでアルファベット順に表示し、文字を選択するとリストがその文字に移動するアルファベット順のスクロールバーを持っています。ただし、ANY 行が選択されている場合は、データベースの最後の行の情報がすべて送信されます。テキストプロパティを持つ行にタイトル要素が必要だと思ったので、そのタイトルを取得して渡す tableview.addEventListener を持つことができましたが、機能しません。これが私が使用しているコードです。誰かが私が間違っているところを見て、見てもらえれば幸いです。

var db = (function() {
var api   = {};
    api.all_item_names = function() {
        var conn = Ti.Database.install('mydb.sqlite','clients');
        var results = [];
        var resultSet = conn.execute('select * from clients order by clientname asc');
        while ( resultSet.isValidRow()) {
            results.push({
            clientname:  resultSet.fieldByName('clientname'),
        });
        resultSet.next();
    }
    resultSet.close();
    return results;
};
return api;
}());

var tvrow;
var curheader   = 'A';
var list    = [];
var index   = [];
var data   = [];
var isAndroid   = (Titanium.Platform.name == 'android');

list = ( db.all_item_names() );

for ( var ipos=0; ipos<list.length;ipos++){
    if( list[ipos].clientname[0] != curheader){
        curheader = list[ipos].clientname[0];

        tvrow = Titanium.UI.createTableViewRow({
            height:    40,
            path:'clientdetail.js' ,
            client: list[ipos],
            header:    curheader 
            });
        index.push({title:curheader, index:ipos});
    } else {
        tvrow = Titanium.UI.createTableViewRow({
            height:40,
            path:'clientdetail.js' ,
            client: list[ipos]});
        }   

var title= Titanium.UI.createLabel({ 
    left:    5, 
    top:     2, 
    height:  40, 
    color:   '#000', 
    font: {fontSize: 16, fontWeight: 'bold', fontFamily: (isAndroid?'sans-serif':'Helvetica Neue')}, 
    text:    list[ipos].clientname });
    tvrow.add(title);
    data.push(tvrow);
}

var tableView = Titanium.UI.createTableView({
    data:            data,
    index:           index,
    backgroundColor:'transparent',
    separatorStyle:  Titanium.UI.iPhone.TableViewStyle.GROUPED,
    top:             1,
    width:           '99%'
});

tableView.addEventListener('click', function(e)
    {
        if (e.rowData.path)
        {
            var win = Ti.UI.createWindow({
                url:e.row.path,
                title:title.text
            });

        var clientlist = title.text;
        win.clientlist = clientlist;
        Ti.UI.currentTab.open(win);
    }
});

win.add(tableView);
4

2 に答える 2

2

問題は、使用するループにあります。最終的に(または最後の値)iposであるindex の値にすべてを割り当てているため、常にその値を取得します。list.lengthこれを回避するために、通常はクロージャが使用され、次のように値が渡されます。

for ( var ipos=0; ipos<list.length;ipos++){
 (function(i){
  if( list[i].clientname[0] != curheader){
   curheader = list[i].clientname[0];

   tvrow = Titanium.UI.createTableViewRow({
    height:    40,
    path:'clientdetail.js' ,
    client: list[i],
    header:    curheader 
   });
   index.push({title:curheader, index:i});
  } else {
   tvrow = Titanium.UI.createTableViewRow({
    height:40,
    path:'clientdetail.js' ,
    client: list[i]
   });
  }   

  var title= Titanium.UI.createLabel({ 
   left:    5, 
   top:     2, 
   height:  40, 
   color:   '#000', 
   font: {fontSize: 16, fontWeight: 'bold', fontFamily: (isAndroid?'sans-serif':'Helvetica Neue')}, 
   text:    list[i].clientname 
  });
  tvrow.add(title);
  data.push(tvrow);
 })(ipos);
}

編集

おそらく、新しいウィンドウで間違ったタイトルを取得し、最後に利用可能な にアクセスしたと思いますtitle。ただし、titleイベント リスナーで利用できる公開されたものがあります。それはe.row.client.clientname(見た目からは入っているかもしれませんがe.rowData..)にあると思います。つまり、クリックすると、現在選択されているタイトルにアクセスする必要があります。

var tableView = Titanium.UI.createTableView({
 data:            data,
 index:           index,
 backgroundColor:'transparent',
 separatorStyle:  Titanium.UI.iPhone.TableViewStyle.GROUPED,
 top:             1,
 width:           '99%'
});

tableView.addEventListener('click', function(e)
{
 if (e.rowData.path)
 {
  var win = Ti.UI.createWindow({
   url:e.row.path,
   title:e.row.client.clientname
  });

  var clientlist = e.row.client.clientname ? e.row.client.clientname : "No client name";
  win.clientlist = clientlist;
  Ti.UI.currentTab.open(win);
 }
});
于 2013-04-08T01:02:08.683 に答える
0

タイトルが間違っているのは、完全に「title」変数を参照しているためです。代わりに、e.rowData または e.index を使用して、クリックされた行を特定する必要があります。「タイトル」は常に最後に作成したタイトルになります。

バグと解決策の両方をより簡単な方法で示す次の例を検討してください。関数呼び出しで for ループを作成する行をラップしても、これを修正するのに役立たないことに注意してください。

var win = Ti.UI.createWindow({ backgroundColor: '#fff' });

var rows = [], titles = [];
for (var i = 0; i < 20; i++) {
    var row = Ti.UI.createTableViewRow({ height: 40 });
    titles.push('Title ' + i);
    var title = Ti.UI.createLabel({ text: titles[i], textAlign: 'center', color: '#000' });
    row.add(title);
    rows.push(row);
}

var table = Ti.UI.createTableView({
    data: rows
});
table.addEventListener('click', function(evt) {
    alert('WRONG: You clicked ' + title.text + '\n'
        + 'RIGHT: You clicked ' + titles[evt.index]);
});
win.add(table);

win.open();
于 2013-04-08T04:25:05.743 に答える