【问题标题】:Titanium Alloy - 'Global' Listener钛合金——“全球”聆听者
【发布时间】:2017-11-21 19:53:07
【问题描述】:

我有多个“需要”livebar 的窗口,以便整个栏在所有窗口上持续存在。但是,每当调用“更改”函数时,它都会工作并记录,但是我的 $.livebar_datalbl.text 失败并出现以下错误:“未定义不是对象(评估 '$.livebar_datalbl.text = 'State:' + e .description + ' (' + e.state + ')'')"

我的代码结构是否不正确或遗漏了什么?

index.js

(function constructor() {
    audioPlayer = Ti.Media.createAudioPlayer({
        url: 'https://allthingsaudio.wikispaces.com/file/view/Shuffle%20for%20K.M.mp3/139190697/Shuffle%20for%20K.M.mp3',
        allowBackground: true
    });

    audioPlayer.addEventListener('progress', function(e) {
        Ti.API.info('Time Played: ' + Math.round(e.progress) + ' milliseconds');
    });

    audioPlayer.addEventListener('change', function(e) {
        $.livebar_datalbl.text = 'State: ' + e.description + ' (' + e.state + ')';
        Ti.API.info('State: ' + e.description + ' (' + e.state + ')');
    });

    window = Alloy.createController('listen').getView();
    window.open();
})();

livebar.xml

<Alloy>
    <View class="livebar">
        <View class="livebar_livelblcontainer">
            <Label class="livebar_livelbl">LIVE</Label>
        </View>
        <Label class="livebar_datalbl" id="livebar_datalbl">HELLO WORLD</Label>
        <ImageView id="livebar_playpausebtn" class="livebar_playpausebtn"/>
    </View>
</Alloy>

livebar.js

$.livebar_playpausebtn.addEventListener('click', function(event) {
    if (audioPlayer.playing || audioPlayer.paused) {
        audioPlayer.stop();
        if (Ti.Platform.name === 'android')
        {
            audioPlayer.release();
        }
    } else {
        audioPlayer.start();
    }
});

audioPlayer.addEventListener('progress', function(e) {
    Ti.API.info('Time Played: ' + Math.round(e.progress) + ' milliseconds');
});

audioPlayer.addEventListener('change', function(e) {
    $.livebar_datalbl.text = 'State: ' + e.description + ' (' + e.state + ')';
    Ti.API.info('State: ' + e.description + ' (' + e.state + ')');
});

【问题讨论】:

    标签: titanium appcelerator-titanium titanium-alloy appcelerator-alloy


    【解决方案1】:

    audioPlayer.addEventListener 事件只会监听您在其中创建了 audioPlayer 的控制器中的事件,在本例中为 index.js。在您的示例中,livebar.js 中的 audioPlayer.addEventListener 事件无效,因为没有可添加事件的 audioPlayer。

    如果您希望在 index.js 中使用音频播放器,然后更新 livebar 并仍将 livebar 保留在其自己的视图+控制器中,则需要跨控制器触发事件​​。为此,您可以使用Ti.App.fireEvent

    您可以在此处阅读更多信息 - 搜索 “应用程序级事件” 部分

    http://docs.appcelerator.com/platform/latest/#!/guide/Event_Handling

    您可以执行以下操作。

    记住要小心应用范围的事件侦听器,您应该始终删除 那些当你通过下面的功能完成它们时

    Ti.App.removeEventListener("eventlistenername", eventfunctionname);
    

    index.js

    (function constructor() {
        audioPlayer = Ti.Media.createAudioPlayer({
            url: 'https://allthingsaudio.wikispaces.com/file/view/Shuffle%20for%20K.M.mp3/139190697/Shuffle%20for%20K.M.mp3',
            allowBackground: true
        });
    
        audioPlayer.addEventListener('progress', function(e) {
            Ti.API.info('Time Played: ' + Math.round(e.progress) + ' milliseconds');
        });
    
        audioPlayer.addEventListener('change', function(e) {
    
            // set livebareText
            var livebareText = 'State: ' + e.description + ' (' + e.state + ')';
    
            // fire app wide event
            Ti.App.fireEvent("app:updateLivebar",livebareText);
    
            Ti.API.info('State: ' + e.description + ' (' + e.state + ')');
        });
    
        window = Alloy.createController('listen').getView();
        window.open();
    })();
    

    livebar.js

    $.livebar_playpausebtn.addEventListener('click', function(event) {
        if (audioPlayer.playing || audioPlayer.paused) {
            audioPlayer.stop();
            if (Ti.Platform.name === 'android')
            {
                audioPlayer.release();
            }
        } else {
            audioPlayer.start();
        }
    });
    
    // Add App eventlistener to listen for updateSingleProgessBar
    Ti.App.addEventListener("app:updateLivebar", updateLivebar);
    
    function updateLivebar(livebarText){
    
        $.livebar_datalbl.text = livebarText;
        Ti.API.info('State: ' + e.description + ' (' + e.state + ')');
    
    }
    

    【讨论】:

    • 大卫-谢谢。经过一些小的调整后,效果很好。但是,由于 livebar.js 被“包含”在另外两个窗口中,每次我在窗口之间切换时,它都会再次添加侦听器,所以经过几次来回之后,我可能会让它更新标签 10、20、30 次。 (这不是问题,因为你看不到,我在想更多的内存/CPU 使用率)。您对此有什么建议还是我应该在窗口更改时销毁监听器?
    • 有几种方法可以解决这个问题。 1. 仅将视图包含在一个窗口中,但这可能是不可能的。 2.给窗口关闭事件添加一个监听器,然后有一个函数在视图关闭时移除运行Ti.App.removeEventListener
    • 谢谢!我对此有疑问,但可能是我试图设计和布局应用程序的方式。这让我决定放弃以这种方式尝试它并走正确的路线,我现在已经开始在 Swift(本机)中实现它,稍后将研究适用于 Android 的 Java。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2013-09-10
    • 2015-09-17
    相关资源
    最近更新 更多