здесь есть подписка?

я есть странный случай в шаблоне элементов Aurelia с if.bind внутри repeat.for не показывается / скрывается, когда изменяется их базовое свойство. С помощью следующего кода поля редактирования должны отображаться, а кнопка редактирования должна быть скрыта, как только будет нажата кнопка редактирования. Впоследствии кнопки сохранения и отмены должны скрыть поля редактирования и снова отобразить кнопки редактирования.

MyList.ts:

import { computedFrom } from "aurelia-binding";

export class MyList
{
  items: any[] = [{
      "firstName": "Joe",
      "lastName" : "Blow",
      "id": 1
    },
    {
      "firstName": "Jane",
      "lastName" : "Doe",
      "id": 2
    }
  ]

  editingItem: any = null
  isEditing: boolean;

  edit(item){
    this.editingItem = item;
    this.isEditing = true;
  }

  editFirst(item){
    this.editingItem = this.items[0];
    this.isEditing = true;
  }

  undo(){
    // undo logic here
    this.editingItem = null;
    this.isEditing = false;
  }

  save(){
    // Save logic here
    this.editingItem = null;
    this.isEditing = false;
  }
}

MyList.html:

<template>
  <table>
    <tbody>
      <tr repeat.for="item of items">
        <td if.bind="!isEditing">
          <button click.delegate="edit(item)">Edit</button>
        </td>
        <td>${item.firstName}</td>
        <td>${item.lastName}</td>
        <td if.bind="isEditing && editingItem.id == item.id">
          <button click.delegate="save()">Save</button>
          <button click.delegate="undo()">Undo</button>
          <input value.bind="editingItem.firstName" />
          <input value.bind="editingItem.lastName" />
        </td>
      </tr>
    </tbody>
  </table>
</template>

Нажатие на кнопку редактирования ничего не делает. Интересно, если я добавлю

${isEditing}

В любом месте шаблона за пределами repeat.for код работает как положено. Как будто движок рендеринга не знает, как перерисовать элементы внутри цикла повторения.

Это ошибка? Или я что-то делаю глупо?

 Balázs21 сент. 2017 г., 14:42
@ BrunoMarotta Единственный тонкий, г я знаю, что может быть проблематично, если они оба присутствуют на одном элементе. Еще более странно, что такой сценарий работает в Chrome, но не в Firefox и других, и в соответствии с ответом на вопрос об этом, это сделано по замыслу (то есть они не должны работать на одном элементе. Тот факт, что он работает в Chrome или что не желательно). Там нет ничего плохого в использовании их по отдельности, они предназначены для использования ...
 Bruno Marotta21 сент. 2017 г., 10:55
if.bind и repeat.for являются контроллерами шаблонов. Я знаю, что есть некоторые проблемы, смешивая их. Попробуйте использовать show.bind вместо if.bind
 Bruno Marotta25 окт. 2018 г., 11:52
@ Balázs - Это я и имел ввиду. Они не должны смешиваться в одном элементе. Извините за неточность. И я также наблюдал этот эффект, который работает в Chrome, а не в Firefox.
 Balázs21 сент. 2017 г., 14:43
... И имейте в виду, чтоvisible.bind влияет только на визуальный аспект, программы чтения с экрана, сканеры и т. д. по-прежнему будут «видеть» контент, что, в зависимости от условий, не то, что вам нужно.

Ответы на вопрос(1)

Решение Вопроса

создал суть из вашего кода и, как вы сказали, это не работает. Никаких ошибок в консоли тоже нет.

Но когда я инициализировалisEditing это начало работать

isEditing: boolean = false;

Обновленный гист

От @ Balázs в комментариях: Не инициализируяisEditing, это свойство практически не существует - его можно использовать для автозаполнения / IntelliSense, но на самом деле его нет на объекте. Вы можете проверить это, заменивconsole.log вызовите метод редактирования сconsole.log(this.editing);, вы увидите, что этоundefined, Это бытьundefinedАурелия не можетsubscribe к нему (потому что это как если бы его даже не было - никакого геттера / сеттера не существует), и, следовательно, нет никакого способа узнать, когда, если вообще, оно оживает. Тем не менее, что даже явно установить егоundefined отличается от этого, потому что это на самом деле создает свойство, чье значение оказывается равнымundefined.


Также обратите внимание:

Так как вы назначаетеeditingItem непосредственно сitem Вот:

edit(item){
    this.editingItem = item;
    this.isEditing = true;
  }

Что бы вы ни изменили вeditingItem повлияетitem также. Так что даже если выundoизменения будут сохранятьсяitem, Так что вы должны сделатьclone перед назначениемeditingItem.


 Balázs21 сент. 2017 г., 14:34
Объяснение, вероятно, заключается в том, что не инициализируяisEditing, это свойство практически не существует - его можно использовать для автозаполнения / IntelliSense, но на самом деле его нет на объекте. Вы можете проверить это, заменивconsole.log позвонить вedit метод сconsole.log(this.editing);, вы увидите, что этоundefined, Это бытьundefinedАурелия не может подписаться на него (потому что его как будто его там и не было - геттер / сеттер не существует), и поэтому не может знать, когда, если вообще, он оживает.
 Balázs21 сент. 2017 г., 14:48
Да. Если вы закомментируетеthis.isEditing = true; и добавьтеconsole.log(this); в верхней части метода, вы увидите, что объект не содержитisEditing свойство. Важно, чтобы вы закомментировалиthis.isEditing = true; строка, потому что в противном случае браузер будет оценивать объект, когда вы нажимаете «еще 1 ...», а затем он будет присутствовать, потому что к тому времени, когда вы щелкаете объект для исследования, он уже будет установлен, даже если он не не существует изначально.
 adiga21 сент. 2017 г., 14:41
@ Balázs Я обновлю ответ этим объяснением. Когда свойство не инициализируется в машинописи, сгенерированный js не будет иметь свойства. Но я создал класс ES6 в сущности. Это компилируется в функцию конструктора безisEditing?
 Balázs21 сент. 2017 г., 14:36
Обратите внимание, что дажеявно установить его в неопределенное отличается от этого, потому что это на самом деле создает свойство, чьистоимость бывает установлен на неопределенное.
 adiga21 сент. 2017 г., 15:00
@ Balázs спасибо за подробное объяснение. Я удалилeditingItem инициализация (ноль). Но это все еще работало. Это потому, что когда мы делаемthis.editingItem = item;, editItem на самом деле указывает наitem объект в памяти, и это на самом делеitemздесь есть подписка?

Ваш ответ на вопрос