Aurelia 代码>已调整

Aurelia 代码>已调整,aurelia,Aurelia,注意:propertyObserver代码在许多情况下可能不是必需的,但在我的情况下,在调用构造函数时,或者在附加视图时,行并不总是加载的,数据加载程序不会将新数据推送到现有数组中,而是将其替换。替换终止了连接我的collectionObserver的阵列,因此有必要对此进行监视并连接一个新的collectionObserver 查看 <!-- delete button enabled when user selected --> <i class="button fa fa

注意:propertyObserver代码在许多情况下可能不是必需的,但在我的情况下,在调用构造函数时,或者在附加视图时,行并不总是加载的,数据加载程序不会将新数据推送到现有数组中,而是将其替换。替换终止了连接我的collectionObserver的阵列,因此有必要对此进行监视并连接一个新的collectionObserver

查看

<!-- delete button enabled when user selected -->
<i class="button fa fa-times" if.bind="selectedRow" click.delegate="deleteRow()"></i>

<div repeat.for="row of rows" click.delegate="selectedRow = row">
    <i class="fa ${selectedRow == row ? 'fa-check-circle' : 'fa-check-circle-o'}"></i>
    ${row.item1} ${row.item2}
</div>
<list-view rows.bind="users" delete-item.delegate="deleteUser($event)"></list-view>
<!--Changed to call new function -->
<div ... click.delegate="selectClick($index)">
    <i class="fa ${selectedRows.indexOf($index) < 0 ? 'fa-check-circle-o' : 'fa-circle-check'}"></i>
<div ref="rowItems">
   <div ref="rowItems[$index].unselected" repeat.for="row of rows" 
       click.delegate="rowItems[$index].unselected = !rowItems[$index].unselected">
      <i class="fa ${rowItems[$index].unselected ? 'fa-check-circle-o' : 'fa-check-circle'}"></i>
<div repeat.for="row of rows" click.delegate="selectedIndices[$index] = !selectedIndices[$index]">
    <i class="fa ${${selectedIndices[$index] ? 'fa-check-circle' : 'fa-check-circle-o'}"></i>
    ${row.item1} ${row.item2}
</div>
<!-- delete button enabled when user selected -->
<i class="button fa fa-times" if.bind="selectedItemsCount" click.delegate="deleteRow()"></i>

<div repeat.for="row of rows">
    <i class="fa ${selectedItems[row.id] ? 'fa-check-circle' : 'fa-check-circle-o'}"></i>
${row.item1} ${row.item2}
</div>

${row.item1}${row.item2}
我相信奥雷利亚团队会以更优雅的方式处理这一切;但希望这也能帮助其他人


再次感谢peinearydevelopment和Eliran的投入。我同意你们两位的观点,在每一行添加一个isSelected标志将是一个更简单的解决方案。

是的,这将是一个简单的方法。但是,我无法将isSelected添加到数据对象中。按照你的建议做实际上是通过添加一个新属性来更改我的数据对象的结构。正确,抱歉,也许我错过了它,但我没有看到你在问题中说你不能这样做的地方。NP,我加粗了它,以帮助使限制更明显一点——就在那里,在所有其他文本中都很难找到。如果您不想为每个数据对象添加isSelected属性,您可以在旁边保留一个字典,将对象映射到其所选属性state@RHarris我更新了我的答案。但仍然不确定这是否是您正在寻找的。如果不是,您想添加更多关于您的需求的详细信息,以便我们可以帮助您找到合适的解决方案?是的,这是最简单的方法。但是,我无法将isSelected添加到数据对象中。按照你的建议做实际上是通过添加一个新属性来更改我的数据对象的结构。正确,抱歉,也许我错过了它,但我没有看到你在问题中说你不能这样做的地方。NP,我加粗了它,以帮助使限制更明显一点——就在那里,在所有其他文本中都很难找到。如果您不想为每个数据对象添加isSelected属性,您可以在旁边保留一个字典,将对象映射到其所选属性state@RHarris我更新了我的答案。但仍然不确定这是否是您正在寻找的。如果不是,您想添加更多关于您的需求的详细信息,以便我们可以帮助您找到合适的解决方案?为什么不使用
isSelected
“脏”数据呢?项目的选定状态不是真实数据吗?不,isSelected不是数据——这是一个UI问题。当数据对象返回到服务器时,我们不希望在数据库中存储UI状态(特别是像selected as这样的可以改变用户之间的关系的东西,等等)。另一个问题是,这是一个可重用的自定义元素,可用于不同的数据对象。不能保证不会有一个数据对象拥有自己的isSelected属性,该属性可能与UI不相关。为什么不使用
isSelected
“脏”数据呢?项目的选定状态不是真实数据吗?不,isSelected不是数据——这是一个UI问题。当数据对象返回到服务器时,我们不希望在数据库中存储UI状态(特别是像selected as这样的可以改变用户之间的关系的东西,等等)。另一个问题是,这是一个可重用的自定义元素,可用于不同的数据对象。不能保证不会有一个数据对象拥有自己的isSelected属性,该属性可能与UI无关。
<div repeat.for="row of rows" click.delegate="row.isSelected = !row.isSelected">
    <i class="fa ${row.isSelected ? 'fa-check-circle' : 'fa-check-circle-o'}"></i>
    ${row.item1} ${row.item2}
</div>
var selectedRows = rows.filter(function(row) { return row.isSelected; });
<div repeat.for="row of rows" click.delegate="selectedIndices[$index] = !selectedIndices[$index]">
    <i class="fa ${${selectedIndices[$index] ? 'fa-check-circle' : 'fa-check-circle-o'}"></i>
    ${row.item1} ${row.item2}
</div>
selectedIndices = {}
import {BindingEngine} from 'aurelia-binding'
@inject(Element,BindingEngine)

...

selectedItems = {}
selectedItemsCount = 0   //used to enable/disable buttons

constructor(element,bindingEngine){
    this.element = element
    this.bindingEngine = bindingEngine

    this.psub = this.bindingEngine
       .propertyObserver(this,"rows")
       .subscribe((data) => {
            if(this.asub) this.asub.dispose();

            if(!Array.isArray(data)) return;

            this.asub = this.bindingEngine
              .collectionObserver(this.rows)
              .subscribe(changes => {
                  if(changes[0].removed.length){
                      for(let item in this.selectedItems){
                          if(!this.rows.find(v => {return v.id == item})){
                             this.selectedItemsCount -= (this.selectedItems[item] ? 1 : 0)
                             delete this.selectedItems[item]
                          }
                      }
                  }
              })
        })
}    

selectClick(id){
    this.selectedItems[id] = !this.selectedItems[id]

    let total = 0
    for(let item in this.selectedItems){
       total += this.selectedItems[item] ? 1 : 0
    }

    this.selectedItemsCount = total
}

deleteRow(item){
   let responseItem = null
   if(!item){
       responseItem = []
       responseItem = this.rows.filter(v => {return this.selectedItems[v.id]})
   }
   else responseItem = item;

   let event = new CustomEvent('delete-row',{
      detail: {item: responseItem, isList: Array.isArray(responseItem)},
      bubbles: true
   })

   this.element.dispatchEvent(event)
}
<!-- delete button enabled when user selected -->
<i class="button fa fa-times" if.bind="selectedItemsCount" click.delegate="deleteRow()"></i>

<div repeat.for="row of rows">
    <i class="fa ${selectedItems[row.id] ? 'fa-check-circle' : 'fa-check-circle-o'}"></i>
${row.item1} ${row.item2}
</div>