标签的钛合金ListView控件嵌套模式阵列 [英] Titanium Alloy ListView Nested Model Array of Tags

查看:269
本文介绍了标签的钛合金ListView控件嵌套模式阵列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的钛合金版本3.2。我有一个列表视图岗位的集合。我的数据是这样的:

I am using Titanium Alloy version 3.2. I have a collection of posts in a listview. My data looks like this:

  [ 
   { 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。这仅适用于用户名和形象。我无法弄清楚如何将标签添加到每个岗位。

And here is the xml. This works only for username and image. I can't figure out how to add the tags to each post.

   <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>

和我的控制器code(不带标签)

And my controller code (without the tags)

   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来完成,但我会preFER使用ListView控件性能方面的原因。

How can I add tags (that are clickable) to the post if I am supposed to declare EVERY view in the template before hand? Each tags array in my example would need a different number of views depending on the array length. Each tag would ideally be its own UI.Label element. I believe this can be done using a TableView, but I would prefer using ListView for performance reasons.

推荐答案

我想我知道你需要什么,在这种情况下,由于要动态生成每个项目(例如,当你与你的ListView打开窗口的场景空第一和调用API来获得远程数据并填充ListView控件与所述数据)则需要使用自己的控制器声明的ItemTemplate。

I think I know what you need, in this case since you want to generate each item dynamically (for example, a scenario where you open your window with your ListView empty first and make an API call to get remote data and fill the ListView with said data) you will need to use ItemTemplates declared in their own controllers.

您只需要创建一个新的控制器像正常并在视图中的XML你把你的ItemTemplate:

You just create a new controller like normal and in the view xml you put your 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你需要定义样式模板,例如可以这样说:

In your tss you put all of the styles referred to each element in your template, since you didn't provide a tss example I can't tell what are your style properties, but in the tss you need to define the style of the template, for example lets say something like:

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

要与ListItems的填写您的ListView动态,你需要从你的API做这样的事情在你的回调:

To fill your ListView with ListItems dynamically, you will need to do something like this in your callback from your 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动态填补。现在有一些额外的步骤,你可以做。

And voila, you get your ListView filled dynamically. Now there are some extra steps you can do.

在模板控制器,你可以将其留空,因为ListView控件可以管理的 itemClick在的事件,但如果你想不同的动作发生时,在列表项某一个元素来触发,则需要指定功能,在您的控制器为每个元素调用。

In your template controller you can leave it blank since the ListView can manage the itemclick event, but if you want different actions to take place when a certain element in the Listitem to trigger, you need to specify the functions to be called in your controller for each element.

例如假设你通过一个名为属性的 dataInfo 的您的ImageView并在模板中像这样的标签:

For example lets say you passed a property called dataInfo to your ImageView and your Label in your template like this:

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和标签调用不同的功能,你需要改变你的XML是这样的:

And you want the ImageView and the Label to call different functions, you will need to change your xml like this:

<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>

在你的控制器,你将宣布各功能:

In your controller you will declare each function:

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接收不同的电子的,即使你使用相同的函数对象。在iOS中传递给事件源无论属性可以直接访问的 e.source.propertyName 的,而在Android中,你需要访问到项的 e.section 的使用的 e.itemIndex 的,在这之后您检索与该项目内部视图中的 e.bindId 的关联吧。

Now you might ask, why do check for the operative system name, well that is because Android and iOS receive different e objects even if you use the same function. In iOS whatever property you pass to the source of the event can be accessed directly with e.source.propertyName while in Android you need to access to the item in e.section using e.itemIndex, after that you retrieve the view inside the item with the e.bindId associated to it.

一对ListItems的被更新列表项内的意见,要做到这一点,你需要更新你想直观地更改,并为其分配一个不同的模板整个项目,但速度的最大限制,在此做你赢了'T能够发现任何的滞后,严重ListView的表现是另一回事,不像滚动型,让我们不要谈可怕和马车的TableView。

One of the biggest restrictions on ListItems is updating the views inside a ListItem, to do this you need to update the whole item you want to change visually and assign it a different template, but the speed at which this is done you won't be able to notice any lag, seriously ListView's performance is something else, unlike ScrollView and let's not talk about the horrible and buggy TableView.

一个警告,钛SDK 3.2.0.GA的还有中的ItemTemplate导致的看法子视图里在模板中改变自己的zIndex的Andr​​oid中没有办法控制它的错误,也有这两个已知实例:
如果使用的是没有设置的子视图的布局。这可能会导致为应显示另一个视图下方来在它上面的景色

A warning, as of Titanium SDK 3.2.0.GA there's a bug in ItemTemplates that causes for views inside child views in the template to change their zIndex in Android with no way to control it, there are two known instances for this: If you use a don't set the layout in a child view: this could cause for a view that should be displayed beneath another view to come on top of it.

如果您在子视图中使用垂直布局。这可能会导致为每个视图的位置被加密,这是因为zIndex的改变显示器的垂直布局的顺序

If you use a vertical layout in a child view: this could cause for the positions of each view to be scrambled, this is because zIndex alters the order of display in a vertical layout.

此错误是随机触发,Appcelerator的团队没有把太多的工作就可以了,在这里检查JIRA票的 TIMOB-16704

This bug is triggered randomly and the Appcelerator team hasn't put much work on it, check the JIRA ticket here TIMOB-16704.

如果你使用模板固定安置的意见和确保​​没有视图来在另一个上面,还记得没有垂直布局后,未与水平测试,这一点,但我个人这样就可以避免尽量避免水平布局自scrollviews使用时也有与之相关的其他错误,正常的意见,等等。

This can be avoided if you use a template with fixed positioned views and making sure no view comes on top of another, also remember no vertical layouts, haven't tested this with horizontal but personally I try to avoid horizontal layouts since there are other bugs related to it when used in scrollviews, normal views, etc.

修改

您可能需要使用该做的另一件事是分配不同的面貌呈现你的项目,你必须选择:

Another thing you might want to do with this is to assign a different look to the items you render, you have to options:


  • 要当你声明列表项应用样式。

  • 要取决于一系列的条件应用不同的布局,每个列表项。

有关,你需要忽略或覆盖在模板中某些属性的声明中的第一个选项:

For the first option you need to omit or overwrite the declaration of certain properties in your template:

例如,让我们使用不同的背景颜色其属性的 fooA 的存在,并且另一种颜色,如果它不:

For example, let's use a different background color where the property fooA exists and another color if it doesn't:

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,布局等。

You can change width, height, backgroundColor, layout, etc. according to your needs.

现在,如果你想每个项目有一个独特的外观(即不同的视图来显示不同​​的内容),也许不同的行为,你需要使用不同的模板。

Now if you want each item to have a distinct look (meaning different views to display different content) and perhaps a different behavior, you'll need to use different templates.

这听起来令人厌烦,但它不是,模板是快速创建,一旦你习惯了它并不需要很长时间,另一种镇定剂可能是,如果你想11个不同的外观,这可能意味着你将需要11模板,但是这是一个极端的情况下,你可能要重新考虑,如果你正在处理的许多模板你的用户界面。

This might sound bothersome but it is not, templates are fast to create once you get used to them which doesn't take long, another downer might be that if you want 11 different looks, that might mean you'll need 11 templates but that's a extreme case and you might want to rethink your UI if you're dealing with that many templates.

虽然严格,项目模板提供了各种选项供你使用,一点点想象力是必要把所有的可能性的唯一因素。

Although restrictive, item templates offer a wide array of options for you to use, a little of imagination is the only ingredient necessary to bring out all of the possibilities.

编辑2

我终于明白了什么是你的问题,如果你需要创建一个模板,其内容的变化,根据斧头的变量,那么你应该尝试声明你的ListView控制器上的模板,但这应该打开窗户是你会之前完成展示在ListView自的模板的属性只能在创建设置,您应该增加类似:

I finally understood what was you problem, if you need to create a template whose content changes according to a x variable, then you should try declaring the template on your ListView controller, but this should be done before opening the window were you will be showing the ListView since the templates property can only be set on creation, you should add something like:

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控制器检索模板:

And in your ListView controller you retrieve the template:

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

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

这应当将模板添加到您的ListView,你也可以建立在你的控制器ListView控件,而不是在你的XML合金宣布它,使用适合您的需求更多的人。

This should add the template to your ListView, you can also create the ListView in your controller instead of declaring it in your Alloy xml, use the one that fits your needs more.

这篇关于标签的钛合金ListView控件嵌套模式阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆