gpt4 book ai didi

javascript - 钛合金ListView标签的嵌套模型数组

转载 作者:行者123 更新时间:2023-11-30 08:46:20 25 4
gpt4 key购买 nike

我正在使用3.2版钛合金。我在列表视图中有一系列帖子。我的数据如下所示:

  [ 
{ username: 'dude', imageUrl: 'url', tags: ['tag1','tag2','tag3'] },
{ username: 'wheres', imageUrl: 'url', tags: ['tag1'] },
{ username: 'my', imageUrl: 'url', tags: ['tag1','tag2','tag3','tag4'] },
{ username: 'car', imageUrl: 'url', tags: ['tag1','tag2'] }
]


这是xml。这仅适用于用户名和图像。我不知道如何将标签添加到每个帖子。

   <ListView id="streamListview">

<Templates>
<ItemTemplate name="template" id="template">
<View class="item-container">
<ImageView bindId="pic" class="pic"/>
<Label bindId="username" class="username"/>
</View>
</ItemTemplate>
</Templates>

<ListSection id="section">
<ListItem template="template" class="list-item"/>
</ListSection>

</ListView>


还有我的控制器代码(没有标签)

   var posts = [];
for (var i=0; i<data.length; i++){
var post = {
template : "template",
pic : { image : data[i].get("imageUrl") },
username : { text : data[i].get("username") }
};
posts.push(post);
}
$.section.setItems(posts);


如果我应该事先在模板中声明每个视图,如何将标签(可单击的)添加到帖子中?在我的示例中,每个标签数组将需要不同数量的视图,具体取决于数组的长度。理想情况下,每个标签都是其自己的UI.Label元素。我相信可以使用TableView完成此操作,但出于性能方面的考虑,我宁愿使用ListView。

最佳答案

我想我知道您需要什么,在这种情况下,因为您要动态生成每一项(例如,在这种情况下,您首先打开ListView为空的窗口,然后进行API调用以获取远程数据并用数据),则需要使用在其自己的控制器中声明的ItemTemplates。

您只需像正常创建一个新的控制器,然后在视图xml中放置ItemTemplate:

<Alloy>
<ItemTemplate name="template" id="template">
<View class="item-container">
<ImageView bindId="pic" class="pic"/>
<Label bindId="username" class="username"/>
</View>
</ItemTemplate>
</Alloy>


在您的tss中,将引用每个元素的所有样式都放在模板中,因为您没有提供tss示例,我无法告诉您样式属性是什么,但是在tss中,您需要定义模板的样式,例如,我们可以这样说:

"#template": // this is the id of your template in your xml
{
width : Ti.UI.FILL,
height : '44dp',
backgroundColor : '#FFFFFF'
}


要用ListItems动态填充ListView,您需要在API的回调中执行以下操作:

function displayListItems(items)
{
var itemCollection = [];
for(var i=0; i < items.length; i++)
{
var tmp = {
pic : {
image : items[i].image
},
username : {
text : items[i].text
},
template : 'template' // here goes the name of the template in your xml, **do not confuse name with id, both are different and using one doesn't replace the other**
};
itemCollection.push(tmp);
}
$.ListView.sections[0].items = itemCollection;
}


瞧,您可以动态填充ListView。现在,您可以执行一些额外的步骤。

在模板控制器中,您可以将其保留为空白,因为ListView可以管理itemclick事件,但是如果希望在Listitem中的某个元素触发时执行不同的操作,则需要指定要在控制器中调用的函数,以用于每个元素。

例如,假设您将名为dataInfo的属性传递给ImageView和模板中的Label,如下所示:

function displayListItems(items)
{
var itemCollection = [];
for(var i=0; i < items.length; i++)
{
var tmp = {
pic : {
image : items[i].image
dataInfo : items[i].fooA //lets pass to the ImageView the object fooA
},
username : {
text : items[i].text,
dataInfo : items[i].fooB //lets pass to the Label the object fooB
},
template : 'template' // here goes the name of the template in your xml, **do not confuse name with id, both are different and using one doesn't replace the other**
};
itemCollection.push(tmp);
}
$.ListView.sections[0].items = itemCollection;
}


而且,您希望ImageView和Label调用不同的函数,则需要像这样更改xml:

<Alloy>
<ItemTemplate name="template" id="template">
<View class="item-container">
<ImageView bindId="pic" class="pic" onClick="imageFunction"/> <!-- added onClick event -->
<Label bindId="username" class="username" onClick="labelFunction"/> <!-- added onClick event -->
</View>
</ItemTemplate>
</Alloy>


在您的控制器中,您将声明每个函数:

function imageFunction(e)
{
var dataInfo;
if(Ti.Platform.osname === 'android')
{
var item = e.section.items[e.itemIndex];
var bindObject = item[e.bindId];
dataInfo = bindObject.fooA;
}
else
{
dataInfo = e.source.fooA;
}

}

function labelFunction(e)
{
var dataInfo;
if(Ti.Platform.osname === 'android')
{
var item = e.section.items[e.itemIndex];
var bindObject = item[e.bindId];
dataInfo = bindObject.fooB;
}
else
{
dataInfo = e.source.fooB;
}
}


现在您可能会问,为什么要检查操作系统名称,这是因为即使您使用相同的功能,Android和iOS也会收到不同的e对象。在iOS中,传递给事件源的任何属性都可以使用e.source.propertyName直接访问,而在Android中,则需要使用e.itemIndex访问e.section中的项目,然后再检索项目内部的视图与关联的e.bindId。

ListItems的最大限制之一是更新ListItem内的视图,为此,您需要更新要在视觉上更改的整个项目并为其分配其他模板,但是这样做的速度不会很快能够注意到任何滞后,与ScrollView不同,认真地讲ListView的性能是另外一回事,我们不要再谈论可怕而又有问题的TableView。

警告,从Titanium SDK 3.2.0.GA开始,ItemTemplates中存在一个错误,该错误会导致模板中子视图内的视图在Android中更改其zIndex而无法对其进行控制,对此有两个已知的实例:
如果您使用“不”在子视图中设置布局,则可能会导致一个应显示在另一个视图下方的视图位于其顶部。

如果在子视图中使用垂直布局:这可能会导致每个视图的位置混乱,这是因为zIndex会更改垂直布局中的显示顺序。

该错误是随机触发的,并且Appcelerator团队没有做太多工作,请在 TIMOB-16704处检查JIRA票证。

如果您使用具有固定位置的视图的模板并确保没有视图出现在另一个视图上,还记得没有垂直布局,还没有使用水平测试,则可以避免这种情况,但是我个人尝试避免使用水平布局,因为还有其他错误在滚动视图,普通视图等中使用时与此相关。

编辑

您可能要执行的另一件事是为渲染的项目分配不同的外观,您必须选择:


在声明ListItem时应用样式。
根据一系列条件,对每个ListItem应用不同的布局。


对于第一个选项,您需要忽略或覆盖模板中某些属性的声明:

例如,让我们在属性fooA存在的地方使用不同的背景颜色,在不存在的情况下使用另一种颜色:

function displayListItems(items)
{
var itemCollection = [];
for(var i=0; i < items.length; i++)
{
var properties = {};
if(typeof items[i].fooA !== 'undefined')
{
properties = {
backgroundColor : 'red'
};
}
else
{
properties = {
backgroundColor : 'blue'
};
}
var tmp = {
properties : properties, // properties for the template
pic : {
image : items[i].image
dataInfo : items[i].fooA //lets pass to the ImageView the object fooA
},
username : {
text : items[i].text,
dataInfo : items[i].fooB //lets pass to the Label the object fooB
},
template : 'template' // here goes the name of the template in your xml, **do not confuse name with id, both are different and using one doesn't replace the other**
};
itemCollection.push(tmp);
}
$.ListView.sections[0].items = itemCollection;
}


您可以根据需要更改宽度,高度,backgroundColor,布局等。

现在,如果您希望每个项目都具有独特的外观(意味着不同的视图以显示不同的内容)并且可能具有不同的行为,则需要使用不同的模板。

这听起来很麻烦,但事实并非如此,一旦您习惯了模板,就可以很快地创建它们,并且不需要很长时间,另一个缺点是,如果您想要11种不同的外观,可能意味着您需要11个模板,但是一个极端的情况,如果要处理那么多的模板,则可能需要重新考虑UI。

尽管有局限性,但项目模板提供了多种选择供您使用,但只有一点点的想像力才能发挥所有可能性。

编辑2

我终于明白了您的问题所在,如果您需要创建一个模板,其内容根据ax变量而变化,那么您应该尝试在ListView控制器上声明该模板,但这应该在打开窗口之前完成,否则将显示由于只能在创建时设置模板属性,因此需要使用ListView:

function createTemplate(items)
{
var template = {};
for(var i=0; i < items.length; i++)
{

template.childTemplates = [];
for(var j=0; items[i].tags.length; j++)
{
var childTemplate = {
type: 'Ti.UI.Label',
bindId: 'tag' + j,
properties : {
width : Ti.UI.SIZE, // Here you define how your style
height : Ti.UI.SIZE,
font : {
fontSize : '18dp'
},
text : items[i].tags[j].text // you can pass the text here or if you want to on the later for
}
};
template.childTemplates.push(childTemplate);
}
}
// After this you should end up with a template with as many childTemplates as tags each item have, so send the template to the controller with your ListView
Alloy.createController('ListViewWindow', {customTemplate: template});
}


然后在ListView控制器中检索模板:

var args = arguments[0] || {};
var template = args.customTemplate;

$.ListView.templates = {'customTemplate' : template}; // before any window open call, do this


这应该将模板添加到您的ListView中,您还可以在控制器中创建ListView而不是在Alloy xml中声明它,请使用更适合您需求的模板。

关于javascript - 钛合金ListView标签的嵌套模型数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21722623/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com