【问题标题】:Access property within module (CommonJS style)模块内的访问属性(CommonJS 样式)
【发布时间】:2013-11-25 07:17:45
【问题描述】:

在 Appcelerator Titanium 中,我正在创建一个最初设置为某些文本的标签。然后我添加一个按钮,单击该按钮会调用 scanController 模块,并且该模块需要更改该文本。所以在 scanController 中,我在下面看到的 scanView 模块中调用setResultTxt() 方法。但是当它说myResultTxt 是空的!这是为什么呢?

我仍在使用 Titanium SDK 1.7.5,因为升级到较新版本时遇到问题。

这是该问题的完整工作示例:

app.js

var win = Titanium.UI.createWindow({  
    backgroundColor:'#fff',
    layout:"vertical"
});
win.open();

var module = require('scanView');

module.createScanPage(win);

scanView.js

var myResultTxt, theButton;

exports.createScanPage = function(theWindow) {
    myResultTxt = Ti.UI.createLabel({
        text: 'Some initial text',
        top:40,
    });
    theWindow.add(myResultTxt);

    theButton = Ti.UI.createButton({
        title: 'Do something',
        top:20
    });
    theButton.addEventListener('click', function() {
        alert('clicked');
        var b = require('scanController');
        b.startScanning();
    });
    theWindow.add(theButton);
};

exports.setResultText = function(str) {
    myResultTxt.text = str;
};

scanController.js

exports.startScanning = function() {
    var a = require('scanView');
    a.setResultText('My new text');
};

【问题讨论】:

  • 我使用 Titanium SDK 3.1.4 运行您的代码,并且运行正常。问题出在代码的不同部分,或者是旧 SDK 的问题,最好弄清楚如何更新到最新版本。

标签: javascript titanium titanium-mobile appcelerator-mobile commonjs


【解决方案1】:

虽然循环引用应该使用 CommonJS (This thread suggests it) 我个人避免使用它们,因为你可能会得到意想不到的结果,尤其是在 Titanium 和不同平台上。

您可以使用回调或事件侦听器,在您的情况下都可以。

以下是回调解决方案的示例:

scanView.js

theButton.addEventListener('click', function() {
     var b = require('scanController');
     // You could pass an existing function as well 
     b.startScanning(function(response) {
         if(response && response.text) {
             myResultTxt.text = response.text;
         }
     });
});

scanController.js

exports.startScanning = function(callback) {
    callback({ text:'My new text'});
};


编辑:
要使任何模块都可以使用 setText,您可以设置一个全局事件监听器。 (我知道有些人认为这是不好的做法,主要是因为可能存在内存泄漏,但如果你在背后清理它是一个有价值的功能)。

app.js

Ti.App.addEventListener('app:setScanText', module.setResultText);


scanController.js

exports.startScanning = function() {
    Ti.App.fireEvent('app:setScanText', { text: 'My new text' });
};


scanView.js

exports.setResultText = function(response) {
    if(response && response.text) {
        myResultTxt.text = response.text;
    }
};

这是未经测试的。

【讨论】:

  • 这是一个很好的建议,但它不能在我的项目中使用,因为 startScanning() 也被其他模块调用......它不仅在 scanView 模块中被调用,还创建了标签。所以我需要找到一个解决方案,如何从我的项目中的任何地方访问myResultTxt...
  • 啊,我明白了,我已经用 eventListener 示例更新了上面的代码。
  • 我也试过了,但是当使用setResultText() 访问时,myResultTxt 仍然未定义。我想我必须放弃使用 CommonJS 并返回将所有属性和方法附加到单个全局对象...
  • 嗯,触发事件时是否调用了 setResultTxt 函数?您是否尝试在函数中添加警报/调试以检查响应是什么?
  • 是的,setResultText 被调用并且参数正确地保存了传递给它的内容。但由于某种原因,myResultTxt 并不是指原始的 myResultTxt,它只是未定义。我现在很确定这是旧 SDK 中的一个错误...
猜你喜欢
  • 2015-02-11
  • 1970-01-01
  • 2016-02-26
  • 1970-01-01
  • 1970-01-01
  • 2018-06-03
  • 2016-06-08
  • 2021-11-29
  • 2017-05-18
相关资源
最近更新 更多