2016-03-24 8 views
1

Ich versuche class.bind in einer Weise zu verwenden, die es von checked.bind abhängig macht.Problem mit Aurelia class.bind mit checked.bind

Mein Anwendungsfall ist ziemlich einfach. Ich habe eine Liste von Elementen, die mit einer table angezeigt werden. Jede Zeile dieser Tabelle hat eine checkbox. Ich möchte eine Zeile als "ausgewählt" markieren, wenn das entsprechende checkbox (der Zeile) überprüft wird. Hierfür hat ich verwenden folgende Bindung:

<table class="table table-striped table-hover table-responsive"> 
    <tbody> 
     <tr repeat.for="item of items" class.bind="$parent.selectedItems.indexOf(item)>-1?'info':''"> 
     <td> 
      <input type="checkbox" checked.bind="$parent.selectedItems" model.bind="item" /> 
     </td> 
     <td>${item.id}</td> 
     <td>${item.name}</td> 
     </tr> 
    </tbody> 
</table> 

Allerdings ist das gleiche nicht wie vorgesehen funktionieren, und dies kann in this plunk zu sehen.

Als Abhilfe habe ich eine getter mit @computedFrom('selectedItems', 'items') und/oder declarePropertyDependencies(App, 'classes', ['selectedItems', 'items']); wie folgt:

import {computedFrom, declarePropertyDependencies} from "aurelia-framework"; 

export class App { 
    ... 

    @computedFrom('selectedItems', 'items') 
    get classes() { 
     const self = this; 
     const retval= self.items.map((item: any) => { 
      return self.selectedItems.indexOf(item) > -1 ? "info" : ""; 
     }); 

     return retval; 
    } 
} 

//declarePropertyDependencies(App, 'classes', ['selectedItems', 'items']); 

Aber auch das funktioniert nicht wie hier in diesem workaround plunk zu sehen ist.

Es funktioniert nur, wenn keiner von @computedFrom und/oder declarePropertyDependencies verwendet wird, und das beinhaltet offensichtlich Dirty-Checking.

Gibt es einen sauberen Weg, dies zu tun?

Antwort

4

Das Bindungssystem wird den Klassenbindungsausdruck class.bind="$parent.selectedItems.indexOf(item)>-1?'info':''" jederzeit erneut bewerten, wenn sich eine im Ausdruck verwendete Eigenschaft ändert. Die Eigenschaft selectedItems ändert sich nie, es bleibt dieselbe Array-Instanz. Verständlicherweise ist das ein wenig verwirrend, weil die Array-Instanz mutiert. Hier ist eine Problemumgehung, die Sie verwenden können: Fügen Sie dem Bindungsausdruck "selectedItems.length" hinzu. Wir wissen, dass sich das ändern wird, wenn Elemente aus dem Array verschoben werden.

Hier ist ein Beispiel: https://gist.run?id=09d32941842352ff0025

app.html

<template> 
    <p>${message}</p> 
    <table class="table table-striped table-hover table-responsive"> 
    <tbody> 
     <tr repeat.for="item of items" class.bind="selectedItems.length === 0 || selectedItems.indexOf(item) === -1 ? '' : 'info'"> 
     <td> 
      <input type="checkbox" checked.bind="selectedItems" model.bind="item" /> 
     </td> 
     <td>${item.id}</td> 
     <td>${item.name}</td> 
     </tr> 
    </tbody> 
    </table> 
    ${selectedItems.length} items selected 
</template> 

app.js

export class App { 
    constructor(router) { 
    this.message = "Hello World!"; 
    this.items = [{ 
     id: 1, 
     name: "A" 
    }, { 
     id: 2, 
     name: "B" 
    }, { 
     id: 3, 
     name: "C" 
    }]; 
    this.selectedItems=[]; 
    } 
}