我正在尝试修改以下的钛Widget。
https://github.com/pablorr18/TiFlexiGrid
这是一个照片库,您可以在其中获取远程图像并将其存储在图库中。有关问题的背景,请参阅此问题:
Modifying widgets in an alloy project
我遇到的麻烦是,就像该线程中的海报所说的那样,我无法使用回调函数将变量传递给我的控制器(在本例中为图像URL)。在Widget.JS中,在文件的底部,我添加了以下代码:
Widget.xml
<Alloy>
<View id="fgMain">
<Button title="Click me!" onTouchend="buttonClicked"/>
<View id="fgWrapper">
<ScrollView id="fgScrollView"/>
</View>
</View>
</Alloy>
Widget.js
// This will hold our callback
var onClickCallback;
// The button has been clicked, call callback
function buttonClicked(e) {
if(typeof(onClickCallback) === 'function') {
onClickCallback({ type:'clicked!' }); }
}
// Assign our callback
function onClick(callback) {
onClickCallback = callback;
};
// Make the onClick function public
exports.onClick = onClick;
然后我希望进入我的主应用程序并从回调函数获取这样的值:
photoGallery.xml
<Alloy>
<Window>
<Widget id="myWidget" src="myWidget" />
</Window>
</Alloy>
photoGallery.js
// Now we can intercept the click within the widget
// and use the values passed
$.myWidget.onClick(function(e) {
alert(e.type);
});
问题是,由于onTouchend事件没有触发,我无法将变量传递给继承小部件的控制器,因为未设置回调函数。
原始的widget.js代码如下:
exports.createGrid = function(args){
var params = args || {};
//Ti.API.info('Params es ---> '+ JSON.stringify(params));
var columns = params.columns || 4;
var space = params.space || 5;
var data = params.data || {};
var options = params.params || {};
var layout = params.layout || 'gallery';
var screenWidth = params.width || Ti.Platform.displayCaps.getPlatformWidth();
if (OS_ANDROID) {
screenWidth /= Ti.Platform.displayCaps.logicalDensityFactor;
}
var newWidth = screenWidth - space;
var columnWidth = (newWidth / columns) - space;
var frameBGcolor = options.backgroundColor || '#fff';
//ADJUST THE SCROLLVIEW
$.fgScrollView.left = space;
$.fgScrollView.top = space;
$.fgScrollView.right = -1;
$.fgMain.backgroundColor = frameBGcolor;
for (var x=0;x < data.length; x++){
var frame = Ti.UI.createView({
width:columnWidth,
height:columnWidth,
backgroundColor:options.gridColor || '#eee',
top:0,
left:0,
right:space,
bottom:space
});
var overlay = Ti.UI.createView({
width:Ti.UI.FILL,
height:Ti.UI.FILL,
backgroundColor:'transparent',
zIndex:1,
strImage:data[x].image
});
var gridElement;
//TYPE OF LAYOUT
switch(layout){
case('gallery'):
gridElement = Widget.createController('gallery',{
image:data[x].image,
title:data[x].title,
width:columnWidth,
padding:options.padding || 10,
showTitle:options.showTitle || false
}).getView();
overlay.addEventListener('click',function(e){
exports.openModal(e.source.strImage);
});
break;
case('customView'):
gridElement = data[x];
break;
}
frame.add(gridElement);
// This condition makes the overlay not be added if it's not gallery layout.
// It's used to make the custom view, caputre the click method. If not,
// The overlay is on top of it and captures the click.
if(layout == 'gallery')
frame.add(overlay);
$.fgScrollView.add(frame);
};
};
exports.openModal = function(url){
var overlay = Ti.UI.createView({
width:Ti.UI.FILL,
height: Ti.UI.FILL,
backgroundColor:'#000',
opacity:0,
zIndex:100
});
var topView = Ti.UI.createView({
width:Ti.UI.FILL,
height: Ti.UI.FILL,
zIndex:1200,
visible:false
});
//this gets image , adds it to top view
var imgView = Ti.UI.createImageView({
image: url,
width:Ti.UI.SIZE,
height: Ti.UI.SIZE
});
//add it
topView.add(imgView);
$.fgMain.add(overlay);
if (OS_IOS){
//ANIMATION OF OVERLAY
overlay.animate({opacity:0.7,duration:200});
//ANIMATION FOR POP EFFECT
var t = Titanium.UI.create2DMatrix();
t = t.scale(0);
var a = Titanium.UI.createAnimation();
a.transform = t;
a.duration = 200;
$.fgMain.add(topView);
topView.animate(a);
a.addEventListener('complete', function(){
topView.visible = true;
var t2 = Titanium.UI.create2DMatrix();
t2 = t2.scale(1.2);
topView.animate({transform:t2, duration:200},function(e){
var t4 = Titanium.UI.create2DMatrix();
t4 = t4.scale(1.0);
topView.animate({transform:t4, duration:200});
//alert('animation complete');
//hide cancel button
});
});
}
else{
//ANIMATION OF OVERLAY
overlay.animate({opacity:0.7,duration:200},function(e){
topView.visible = true;
$.fgMain.add(topView);
});
}
topView.addEventListener('click',function(e){
if (OS_IOS){
var t3 = Titanium.UI.create2DMatrix();
t3 = t3.scale(1.2);
var a2 = Titanium.UI.createAnimation();
a2.transform = t3;
a2.duration = 200;
topView.animate(a2);
a2.addEventListener('complete', function(){
var t5 = Titanium.UI.create2DMatrix();
t5 = t5.scale(0);
topView.animate({transform:t5, duration:200},function(e){
$.fgMain.remove(topView);
overlay.animate({opacity:0,duration:200},function(e){
$.fgMain.remove(overlay);
});
});
});
}
else{
$.fgMain.remove(topView);
overlay.animate({opacity:0,duration:200},function(e){
$.fgMain.remove(overlay);
});
}
});
};
exports.clearGrid = function(){
$.fgScrollView.removeAllChildren();
};
从它看,它似乎让一个事件处理程序注册的唯一方法是把它作为一个函数(createGrid)并像这样调用它:
在widget.xml中exports.createGrid
var button = Titanium.UI.createButton({
title : 'Use Picture',
top : 10,
width : 100,
height : 50
});
button.addEventListener('click',function(e)
{
Titanium.API.info(url);
//do not want to store in global variable
Alloy.Globals.urlFromGal = url;
});
//add it
topView.add(imgView);
topView.add(button);
$.fgMain.add(overlay);
但是我不确定如何调整该代码:
// This will hold our callback
var onClickCallback;
// The button has been clicked, call callback
function buttonClicked(e) {
if(typeof(onClickCallback) === 'function') {
onClickCallback({ type:'clicked!' }); }
}
// Assign our callback
function onClick(callback) {
onClickCallback = callback;
};
// Make the onClick function public
exports.onClick = onClick;
这样我就能够访问widget.js范围之外的url变量。我可以使用GLOBAL Variables - 通过将变量存储在一个而不是用于此任务,但是我想避免以这种方式做事。
更新:
无法使其正常工作,但我已将回调添加到事件处理程序中。得到事件处理程序,但不知道如何将回调数据传递给onClick函数:
var onClickCallback;
exports.createGrid = function(args){
var params = args || {};
//Ti.API.info('Params es ---> '+ JSON.stringify(params));
var columns = params.columns || 4;
var space = params.space || 5;
var data = params.data || {};
var options = params.params || {};
var layout = params.layout || 'gallery';
var screenWidth = params.width || Ti.Platform.displayCaps.getPlatformWidth();
if (OS_ANDROID) {
screenWidth /= Ti.Platform.displayCaps.logicalDensityFactor;
}
var newWidth = screenWidth - space;
var columnWidth = (newWidth / columns) - space;
var frameBGcolor = options.backgroundColor || '#fff';
//ADJUST THE SCROLLVIEW
$.fgScrollView.left = space;
$.fgScrollView.top = space;
$.fgScrollView.right = -1;
$.fgMain.backgroundColor = frameBGcolor;
for (var x=0;x < data.length; x++){
var frame = Ti.UI.createView({
width:columnWidth,
height:columnWidth,
backgroundColor:options.gridColor || '#eee',
top:0,
left:0,
right:space,
bottom:space
});
var overlay = Ti.UI.createView({
width:Ti.UI.FILL,
height:Ti.UI.FILL,
backgroundColor:'transparent',
zIndex:1,
strImage:data[x].image
});
var gridElement;
//TYPE OF LAYOUT
switch(layout){
case('gallery'):
gridElement = Widget.createController('gallery',{
image:data[x].image,
title:data[x].title,
width:columnWidth,
padding:options.padding || 10,
showTitle:options.showTitle || false
}).getView();
overlay.addEventListener('click',function(e){
exports.openModal(e.source.strImage);
});
break;
case('customView'):
gridElement = data[x];
break;
}
frame.add(gridElement);
// This condition makes the overlay not be added if it's not gallery layout.
// It's used to make the custom view, caputre the click method. If not,
// The overlay is on top of it and captures the click.
if(layout == 'gallery')
frame.add(overlay);
$.fgScrollView.add(frame);
};
};
exports.openModal = function(url){
var overlay = Ti.UI.createView({
width:Ti.UI.FILL,
height: Ti.UI.FILL,
backgroundColor:'#000',
opacity:0,
zIndex:100
});
var topView = Ti.UI.createView({
width:Ti.UI.FILL,
height: Ti.UI.FILL,
zIndex:1200,
visible:false
});
//this gets image , adds it to top view
var imgView = Ti.UI.createImageView({
image: url,
width:Ti.UI.SIZE,
height: Ti.UI.SIZE
});
var button = Titanium.UI.createButton({
title : 'Use Picture',
top : 10,
width : 100,
height : 50
});
button.addEventListener('touchend',function(e)
{
//Titanium.API.info(url);
if(typeof(onClickCallback) === 'function') {
onClickCallback({ type:'clicked!' }); }
});
//pass callback, not working
onClick();
//add it
topView.add(imgView);
topView.add(button);
$.fgMain.add(overlay);
if (OS_IOS){
//ANIMATION OF OVERLAY
overlay.animate({opacity:0.7,duration:200});
//ANIMATION FOR POP EFFECT
var t = Titanium.UI.create2DMatrix();
t = t.scale(0);
var a = Titanium.UI.createAnimation();
a.transform = t;
a.duration = 200;
$.fgMain.add(topView);
topView.animate(a);
a.addEventListener('complete', function(){
topView.visible = true;
var t2 = Titanium.UI.create2DMatrix();
t2 = t2.scale(1.2);
topView.animate({transform:t2, duration:200},function(e){
var t4 = Titanium.UI.create2DMatrix();
t4 = t4.scale(1.0);
topView.animate({transform:t4, duration:200});
//alert('animation complete');
//hide cancel button
});
});
}
else{
//ANIMATION OF OVERLAY
overlay.animate({opacity:0.7,duration:200},function(e){
topView.visible = true;
$.fgMain.add(topView);
});
}
topView.addEventListener('click',function(e){
if (OS_IOS){
var t3 = Titanium.UI.create2DMatrix();
t3 = t3.scale(1.2);
var a2 = Titanium.UI.createAnimation();
a2.transform = t3;
a2.duration = 200;
topView.animate(a2);
a2.addEventListener('complete', function(){
var t5 = Titanium.UI.create2DMatrix();
t5 = t5.scale(0);
topView.animate({transform:t5, duration:200},function(e){
$.fgMain.remove(topView);
overlay.animate({opacity:0,duration:200},function(e){
$.fgMain.remove(overlay);
});
});
});
}
else{
$.fgMain.remove(topView);
overlay.animate({opacity:0,duration:200},function(e){
$.fgMain.remove(overlay);
});
}
});
};
exports.clearGrid = function(){
$.fgScrollView.removeAllChildren();
};
// Assign our callback
function onClick(callback) {
onClickCallback = callback;
alert(onClickCallback);
};
// Make the onClick function public
exports.onClick = onClick;