Как ссылаться на виджет Tabrisjs без идентификатора, без класса, после создания

Вот пример (работает на игровой площадке), который создает виджеты с циклом forEach. я использую index создать уникальный идентификатор для виджетов:

id: 'txiFirstName' + (index + 1)

Я понимаю, что могу изменить свойства виджетов, используя идентификаторы и классы, что очень полезно.

Можно ли ссылаться на виджеты без .apply? Что-то вроде:

txiFirstName[1] //which doesn’t work

Спасибо,

КОД (Tabrisjs 2.5)

const {Button, CheckBox, TextInput, TextView, ui} = require('tabris')

let persons = [
  { 'firstName': 'Bob', 'lastName': 'Smith', 'member': true },
  { 'firstName': 'Bill', 'lastName': 'Jones', 'member': false },
  { 'firstName': 'Fred', 'lastName': 'Picard', 'member': true }
]

let d = new Date()

persons.forEach((person, index) => {
  console.log(person.firstName + ' ' + person.lastName + ' Member: ' + person.member)

  let txiFirstName = new TextInput({
    id: 'txiFirstName' + (index + 1),
    left: 20, top: 'prev() 20', width: 80,
    text: person.firstName
  }).appendTo(ui.contentView)

  let txiLastName = new TextInput({
    id: 'txiLastName' + (index + 1),
    left: 110, top: 'prev() -20', width: 100,
    text: person.lastName
  }).appendTo(ui.contentView)

  let chkMember = new CheckBox({
    id: 'chkMember' + (index + 1),
    class: 'chkMember',
    right: 5, top: 'prev() -20',
    checked: person.member
  }).appendTo(ui.contentView)

  let txvDate = new TextView({
    class: 'txvDate',
    right: 5, top: 'prev()',
    text: d
  }).appendTo(ui.contentView)
}) // end forEach

let btnNotMember = new Button({
  centerX: 0, top: 'prev() 20',
  text: '  Make all persons non-members'
})
  .on('select', () => {
    ui.contentView.apply({'.chkMember': {checked: false}})
  }).appendTo(ui.contentView)

let btnMember1 = new Button({
  centerX: 0, top: 'prev() 20',
  text: 'Change member 1 to Sherlock'
})
    .on('select', () => {
      ui.contentView.apply({'#txiFirstName1': {text: 'Sherlock'}})
    }).appendTo(ui.contentView)

let btnUpdateDate = new Button({
  centerX: 0, top: 'prev() 20',
  text: 'Update date'
}).on('select', () => {
  let d = new Date()
  ui.contentView.apply({'.txvDate': {text: d}})
}).appendTo(ui.contentView)

Снимок экрана iOS

1 ответ

Решение

Это зависит от того, как вы структурируете свой код.

Ваш пример показывает, что вы зацикливаетесь на массиве для создания макета списка. Если макет в конечном итоге оказывается выше, чем может поместиться на экране, при переключении на CollectionView, Это потому что CollectionView будет отображать только то, что необходимо для отображения на экране, тогда как рисование каждого элемента сохранит весь макет в памяти. Так что если ваш persons массив будет становиться большим, я бы переключил его на CollectionView и, похоже, у вас уже есть код для этого стиля.


На все виджеты можно ссылаться из переменной JavaScript, например:

let square = new Composite({
    centerX: 0, centerY: 0,
    height: 25,
    width: 25,
}).appendTo(ui.contentView);

square.background = 'blue';

В вашем примере этот код:

txiFirstName[1]

не будет работать, потому что:

  1. Тип txiFirstName имеет тип tabris.TextInput и не является массивом
  2. txiFirstName объявлено с let внутри функции стрелки и, следовательно, находится только в области видимости внутри этого цикла *. Больше нигде это не определено.

Похоже, вы поняли это с тремя кнопками внизу. Вы можете ссылаться на виджет напрямую, используя идентификатор или класс, который вы назначаете виджету. Если по какой-то причине вы не хотите назначать им идентификаторы, вам нужно вставить ваши элементы в переменную, которая имеет правильную область видимости: т.е. использовать var внутри цикла, чтобы поднять его или объявить вне цикла.

* В частности, это только в области во время этой итерации цикла. Следующая итерация цикла не будет иметь доступа ни к одной из переменных, которые были установлены во время предыдущей итерации.

Другие вопросы по тегам