【问题标题】:function iterates through loop and works once but never again函数遍历循环并工作一次但不再工作
【发布时间】:2011-04-14 18:12:07
【问题描述】:

我正在调用 Titanium 模态窗口以打开然后运行一个函数,该函数会像这样循环一些数据;

窗口 1:

var win = Ti.UI.createWindow({
    url: 'window2.js'
    modal: 1
});
win.open();

窗口 2:(从窗口 1 调用)

win = Ti.UI.currentWindow;

function doLoop() {
    Ti.API.info('doLoop fn called');
    // I've tracked the issue down to here
    var m = 0;
    for(var i in list) { m++; }

    Ti.API.info(m);
    Ti.API.info('finished');
}

win.addEventListener('open', function() {
    // list is dynamically generated and passed through successfully from window1.js
    doLoop();
});

doLoop()每次调用成功,list每次调用成功。

第一次运行就完美了。第二次(不是第一次)运行它需要时间来暂停并运行循环,但 m 永远不会增加?循环暂停后输出“完成”。

有什么想法吗?

function buildMediaItemsSelectionTable() {
    var mediaCount = 0, i;

    for(i in mediaItemsSelectionList[0]) { mediaCount++; }

    for(i=0,l=mediaCount;i<l;i++) {
        addMediaItemsSelectionSongsRow(i);
    }
}

【问题讨论】:

  • 如果有帮助,列表存储在 Ti.App.Properties.getList('list');所以函数 doLoop() 每次都可以访问它。
  • JSON 对象,我相信大约 3 深的对象更多,但我只在拳头深度之后
  • 好的,上面的代码更新得更好。我已经验证了该列表每次都与 Titanium 等效 Ti.API.info(list) 一起存在,并且它确实存在并且通过该循环运行,但第二个循环永远不会运行,因为第一个循环永远不会增加
  • 我向您保证,该列表永远不会为空。如果不是第一次,它将无法正常运行。我已经进行了几个测试,并在第二次将其限制在第一个循环中作为问题。我更想知道该循环是否正在缓存而不是第二次运行或类似的东西?
  • 是的,是的,我什至验证了mediaItemsSelectionList[0] === mediaItemsSelectionList[0],它正在检查缓存列表是否与每次调用都为真的动态版本完全相同?

标签: javascript mobile titanium appcelerator


【解决方案1】:

我在这里看到了几个问题。

首先,您的buildMediaItemsSelectionTable() 函数存在问题

  1. 你的 for..in 循环可能会捕捉到你没有捕捉到的对象属性
  2. 不需要双循环

以下是这些修改

function buildMediaItemsSelectionTable()
{
  var i = 0, p;

  for ( p in mediaItemsSelectionList[0] )
  {
    if ( mediaItemsSelectionList[0].hasOwnProperty( p ) )
    {
      addMediaItemsSelectionSongsRow( i++ );
    }
  }
}

另一个问题是我不得不猜测的问题,因为您没有提供足够的代码。我假设您通过 Titanium 的变量转发将 list 传递给模态。也许是这样的?

var win = Ti.UI.createWindow({
    url:   'window2.js'
  , modal: 1
  , list:  [1,2,3]
});

有些东西必须反复打开模态,对吗?也许是一个按钮

var button = Ti.UI.createButton( {title: 'Modal'} );
Ti.UI.currentWindow.add( button );

button.addEventListener( 'click', function()
{
  win.open();
});

但是根据您的描述,list 发生了变化,所以让我们创建一个随机列表生成器并将其插入到我们的页面中,整个事情看起来像这样

var win = Ti.UI.createWindow({
    url:   'window2.js'
  , modal: 1
  , list:  randomList()
});

var button = Ti.UI.createButton( {title: 'Modal'} );
Ti.UI.currentWindow.add( button );

button.addEventListener( 'click', function()
{
  win.open();
});

function randomList()
{
  // Random return an array with 3, 5, or 7 items
  return [[1,2,3],[1,2,3,4,5],[1,2,3,4,5,6,7]][Math.floor(Math.random()*2)];
}

这里有什么问题? randomList() 只被调用一次,不管你打开模态多少次。即使 window1 是导航或选项卡组的一部分,创建模式窗口的代码在任何情况下都不会重新执行。

如果您希望每次都将新列表转发到模态,则必须每次都生成新列表

button.addEventListener( 'click', function()
{
  win.list = randomList();
  win.open();
});

【讨论】:

  • 这些答案都不正确,但彼得你是对的,我应该发布更多代码。但是现在已经解决了,正是您在上面发布的内容让我找到了解决方案,或者至少是一种不同的思考方式,谢谢。
【解决方案2】:

您的“}”似乎放错了位置。现在,您有一个带有单个(可能是意外)副作用的循环 - m 计数到列表的长度,然后调用 API.info 与列表的长度。

你可能想要:

function doLoop() {
    Ti.API.info('doLoop fn called');
    // I've tracked the issue down to here
    var m = 0;
    for(var i in list) { 
        m++;

       Ti.API.info(m);
       Ti.API.info('finished');
    }

}

【讨论】:

  • 谢谢。在大多数情况下,我会完全同意,但在这种情况下,我使用m 来获取对象的长度,然后以原始方式调用另一个 for 循环 for(i=0;i&lt;m;i++),接下来运行。它第一次运行完美,但之后第二次循环不会每次都运行,因为m 永远不会再次设置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
  • 2018-08-23
  • 1970-01-01
  • 2020-05-21
  • 1970-01-01
相关资源
最近更新 更多