选择器更改事件未在 Titanium 中首次触发

Posted

技术标签:

【中文标题】选择器更改事件未在 Titanium 中首次触发【英文标题】:picker change event not firing for first time in Titanium 【发布时间】:2015-10-01 08:48:41 【问题描述】:

我在我的 Tiatnium 应用程序中使用选择器。

Picker 数据正在从 json 响应加载。我首先将 API 数据存储在 Temporary 数组中,然后将数据添加到 Picker。

问题是当我第一次单击选择器元素时,更改事件没有被触发。 第一次点击完成后,如果我点击任何元素,它会按预期工作。

这是它的小代码sn-p

for (var i = sorted.length - 1; i >= 0; i--) 
            pickerData[i] = Ti.UI.createPickerRow(
                title : sorted[i],

        );
            Ti.API.info('From sorted ' + i + sorted[i]);
        
$.picker.add(pickerData);
$.picker.addEventListener('change', function(e) 
            countRow = 0;
            data.length = 0;
            showfilterData(e.row.title, jsonResponse);
        );

那么问题出在哪里。

谁能解释一下?

【问题讨论】:

你能提供一个用于测试的小提琴吗? 我认为很难在小提琴上得到这个,因为它是钛 你能检查一下这个简单的例子是否有效吗?只是为了了解问题出在您发布的代码中还是其他方面...var row1 = Ti.UI.createPickerRow( title : "row1, ); var row2 = Ti.UI.createPickerRow( title : "row2, ); var pickerData = [row1, row2]; $.picker.add(pickerData); $.picker.addEventListener('change', function(e) console.log('clicked on the row '+e.row.title); ); 我试过你的代码......这个问题也伴随着这个代码。所以我猜这个问题是别的。 【参考方案1】:

以下示例运行良好:

index.xml

<Alloy>
    <Window id="mainWindow">
    </Window>
</Alloy>

index.js

var picker = Titanium.UI.createPicker();
var data = [];
data[0]=Ti.UI.createPickerRow(title:'Bananas');
data[1]=Ti.UI.createPickerRow(title:'Strawberries');
data[2]=Ti.UI.createPickerRow(title:'Mangos');
data[3]=Ti.UI.createPickerRow(title:'Grapes');
picker.add(data);
picker.addEventListener('change', function(e) 
    console.log(e.row.title);
);
$.mainWindow.add(picker);
$.mainWindow.open();

每次(也是第一次)单击选择器的一行时,我都会在控制台上获得正确的日志。在 Titanium 4.1.0、ios 8.4 上测试

选择器工作正常。我猜您的代码中还有其他问题(您没有向我们展示的内容)。

如果这个例子不适合你,请告诉我

【讨论】:

嘿,很抱歉回复晚了...我在单独的文件中尝试了这段代码,发现了一些奇怪的问题。如果我在 js 文件中编写它,它会按预期工作,如果我在 XML 中保留选择器文件同样的问题重复。你能尝试同样的吗?...保持选择器在 xml 文件和 js 文件中的数据,看看这是否会出现?【参考方案2】:

这是我第一次回答自己的问题。 对于所有在第一次点击选择器时遇到问题的人,这可能会对您有所帮助。

如果您在 XML 文件中编写选择器,那么您可能会遇到这个问题,因为我们从代码中添加数据并且选择器在窗口打开时已经显示,所以在您的 js 文件中添加选择器...这可能不是技术描述,但我尝试过,所以我认为这适用于所有人。我发布了它不起作用的两种方式(意味着首次点击问题)和它按预期工作的方式。

这是您可能会遇到问题的代码。

<Alloy>
<Window id="winpast" class="container" title="Past issues" onOpen="openpastIssues">
    <View id="view2"    backgroundColor="#A9F5A9" >
        <View id="viewcheck1" >
            <Label id="title"  text="Past Issues"  textAlign="Ti.UI.TEXT_ALIGNMENT_CENTER"></Label>
            <ImageView id="menuImg" image="/images/menu.png" onClick="showsideBar" left="5"></ImageView>
            <Picker id="picker"  selectionIndicator="true"   right="10">
            </Picker>
        </View>
    </View>
</Window>

js文件

for (var i = sorted.length - 1; i >= 0; i--) 
            pickerData[i] = Ti.UI.createPickerRow(
                title : sorted[i],

        );
$.picker.add(pickerData);//picker is added in xml file and data is added now
picker.addEventListener('change', function(e) 
            alert(e.row.title);

        );
$.winpast.open();

上面的 sn-ps 可能与选择器第一次点击有问题。

现在这是我根据@Riccardo Bucco 的建议实施以消除此问题的正确方法

我只是根据他的建议进行了试验,发现了这一点。

这是正确的代码。

<Alloy>
<Window id="winpast" class="container" title="Past issues" onOpen="openpastIssues">
    <View id="view2"    backgroundColor="#A9F5A9" >
        <View id="viewcheck1" >
            <Label id="title"  text="Past Issues"  textAlign="Ti.UI.TEXT_ALIGNMENT_CENTER"></Label>
            <ImageView id="menuImg" image="/images/menu.png" onClick="showsideBar" left="5"></ImageView>
        </View>
    </View>
</Window>

js文件

var picker = Ti.UI.createPicker(
            right:10
        );
for (var i = sorted.length - 1; i >= 0; i--) 
            pickerData[i] = Ti.UI.createPickerRow(
                title : sorted[i],

        );
            Ti.API.info('From sorted ' + i + sorted[i]);
        
picker.add(pickerData);//we add data here and picker is not added yet
$.viewcheck1.add(picker);//after adding whole data we are adding picker in the view so it resolves the first click issue.
 $.winpast.open();

第二种方法对我来说很好,并且选择器没有第一次点击问题。如果我的答案中没有正确提及任何事情,请纠正我。

希望对你有帮助。

【讨论】:

【参考方案3】:

回答这个问题已经很久了,但我也找到了一种使用 Alloy XML 来完成这项任务的新方法。

    在 js 文件中创建选择器在更改事件中效果很好。 如果您已经在 XML 文件中创建了选择器,并且您在 js 文件中添加了选择器行,那么您需要调用以下方法两次。这有点奇怪,但效果很好。

index.xml

<Alloy>
<Window>
    <Picker id="PICKER" width='70%'  onChange="changeValue"></Picker>
<Window>
</Alloy>

index.js

(function setPickerValues() 
   $.PICKER.add(rows)   // rows is an array of Ti.UI.PickerRows

   // call these two lines to make the change event work
   $.PICKER.setSelectedRow(0, 1);   // this will set the picker row to the row at index 1
   $.PICKER.setSelectedRow(0, 0);   // now it is necessary to set row at index 0 again to make it work.
)();

function changeValue(e) 
   Ti.API.info('Current Row = ' + e.rowIndex);

我知道这种方式有点奇怪,但是它工作得很好,并且比在 js 文件中创建整个选择器所需的代码行更少。

【讨论】:

以上是关于选择器更改事件未在 Titanium 中首次触发的主要内容,如果未能解决你的问题,请参考以下文章

单击事件未在引导单选按钮组中触发

选择第一个单选按钮以触发更改事件

beforeShow 事件未在 jQueryUI Datepicker 上触发

Titanium Facebook 模块未在 iOS 7 上完成登录

全屏更改事件未在 Chrome 中触发

SwipeActions 按钮和 ToolBar 按钮触发的多个工作表(项目:)在 SwiftUI 中首次获取 nil 对象