简体   繁体   中英

Access the index of a parent listview in a nested repeater in a Nativescript layout

I have an array that contains multiple arrays of objects with in it that is returned from a web service, lets call it var groups . In my view model it's an observable array.

var groups = [
              [{year:"1986", key2: "foo2"}, {year:"1986", key2:"blah"}],
              [{year:"1987", key2: "baz"}, {year:"1987", key2:"beek"}],
              [{year:"1988", key2: "baz"}, {year:"1988", key2:"beek"}]
             ]

In my xml I'm trying to nest a <Repeater> with in a <Listview> such that each array in the groups array will be a list item, and each object in the inner arrays will be a repeater item. Problem is I have no clue how to access the index of the parent listview items so that I can reference the correct array in the repeater, and I can't find in the documentation how to access the list index from with in the xml. Does anyone know if this is possible? Here's an example of the xml note the ??? in the repeaters iterator....What can I actually put there?

<Listview items="{{ Groups }}">
    <ListView.itemTemplate>
       /* Some other layout content */
      <Repeater items="{{ Groups[parent.index] ??? }}">
        <Repeater.itemTemplate>
          / * the contents of each groups array should display here */
        </Repeater.itemTemplate>
      </Repeater>
    </ListView.itemTemplate> 
</Listview>

EDIT: Just to make it more clear, I basically just want to know how to access the Parent list views index from the repeaters item attribute. That would allow me to display the correct data in the repeater element.

I'm trying to achieve a separated list such as this below. Each array in the groups array is a chunk of data with the same date. So the list view rows (dates) are based on the number of arrays contained in the groups array and the data sections below each date are populated from the data within each of those arrays.

我正在尝试实现一个单独的列表,如下所示。 <code> groups </ code>数组中的每个数组都是具有相同日期的数据块。因此,列表视图行(日期)基于<code> groups </ code>数组中包含的数组数,并且每个日期以下的数据部分都是从每个数组中的数据中填充的。

In NativeScript is not possible to get index of the selected item in Repeater . However one possible decision could be to set unique id for example to Label and to attach tap even to it. When one of the Label has been clicked, you could get its unique id . I am attaching example for this option.

main-page.xml

<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="onPageLoaded">
        <ListView id="listview" items="{{ myItems }}" itemTap="listViewItemTap">
            <ListView.itemTemplate>
                <StackLayout>

                  <Repeater items="{{ myItem2 }}" >
                    <Repeater.itemsLayout>
                      <WrapLayout />
                    </Repeater.itemsLayout>
                    <Repeater.itemTemplate>
                      <Label text="{{ $value.item }}" id="{{$value.key}}" margin="10" onTap="test"/>
                    </Repeater.itemTemplate>
                  </Repeater>
                </StackLayout>
            </ListView.itemTemplate>
        </ListView>
</Page>

main-page.js

var observable_array_1 = require("data/observable-array");
function onPageLoaded(args) {
    var page = args.object;
    var array = new observable_array_1.ObservableArray();
    var listView = page.getViewById('listview');
    array.push({ myItem2: [{ item: "test1", key: "1" }, { item: "test1", key: 'j' }, { item: "test1", key: "3" }] });
    array.push({ myItem2: [{ item: "test6", key: "6" }, { item: "test4", key: "4" }, { item: "test5", key: "5" }] });
    page.bindingContext = { myItems: array };

}
exports.onPageLoaded = onPageLoaded;
function listViewItemTap(args) {
    var itemIndex = args.index;
    var object = args.object;
    console.log(itemIndex);
}
exports.listViewItemTap = listViewItemTap;
function test(args) {
    console.log(args.object.get('id'));
}
exports.test = test;

As NativeScript indeed can not provide indexing inside the nested repeater and based on the example of Nikolay Tsonev it will be a lot easier to just convert your jagged array to array with JSON objects. Here is what you need to do for this code to work with your array.

var groups = [
      [{year:"1986", key2: "foo2"}, {year:"1986", key2:"blah"}],
      [{year:"1987", key2: "baz"}, {year:"1987", key2:"beek"}],
      [{year:"1988", key2: "baz"}, {year:"1988", key2:"beek"}]
];

var resultArray = new ObservableArray();

groups.forEach(subgroup => {
    var jsonArg1 = new Object();
    jsonArg1["myItem2"] = subgroup;
    resultArray.push(jsonArg1);
});

However you have also another solution - you can provide totally diffferent binding source to your nested repeater via $parents[Page].someDataModel For example:

// page.xml
<ListView items="{{ items }}">
    <ListView.itemTemplate>
        <StackLayout>
            <Label text="{{ $value }}" />
            <TextField text="{{ $parents['ListView'].test, $parents['ListView'].test }}" />
        </StackLayout>
    </ListView.itemTemplate>
</ListView>

// page.js
viewModel.set("items", [1, 2, 3]);
viewModel.set("test", "Test for parent binding!");

This as well will require for you to manually convert your two-dimensional array into something with more suitable form. More about $parents this here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM