模块内的访问属性(CommonJS 样式)
Posted
技术标签:
【中文标题】模块内的访问属性(CommonJS 样式)【英文标题】:Access property within module (CommonJS style) 【发布时间】: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 的问题,最好弄清楚如何更新到最新版本。 【参考方案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 中的一个错误...以上是关于模块内的访问属性(CommonJS 样式)的主要内容,如果未能解决你的问题,请参考以下文章
ES6中export , export default , import模块系统总结