2012-01-20 22 views
2

私のアプリケーションでは、いくつかの "データ" ValueCell(20のようなもの)を使用しています。ValueCellが更新されたかどうかを検出するために使用されるValueCellを作成したいと思います。だから私は、このセルが、他のセルの1つが変更されるたびに変更したいと思います。ここでLiftweb - 複数のValueCell状態変更

は私が???の代わりに何を置くべき簡単なコード例

class StringFilter { 

    val referenceList = "foo"::"bar"::"scala"::"lift"::Nil 

    val length = ValueCell[Int](3) 
    val content = ValueCell[String]("") 

    //Here I put some functions to update length or prefix on my webpage 
    def filter(s:String):Boolean = (s.length==length.get)&&(s.contains(content.get)) 

    val changed =ValueCell[???](???) 
    val results= changed.lift(referenceList.filter) 
} 

のですか? WiringUIを使用する必要があるため、最終的にいくつかのセルが必要になっても、ValueCellを使用していないソリューションにもオープンしています。

編集:lengthcontentは細胞である必要はありませんが、彼らは設定可能

を編集する必要があります。いくつかのより多くの研究の後、私はアイデアに来た:SeqCellようcase classを実装するが、これだろうパラメータのCells、および任意の数のセルに対して型を取らないでください。出来ますか?
はここSeqCellの実装です:

final case class SeqCell[T](cells: Cell[T]*) extends Cell[Seq[T]] { 

    cells.foreach(_.addDependent(this)) 

    /** 
    * The cell's value and most recent change time 
    */ 
    def currentValue: (Seq[T], Long) = { 
    val tcv = cells.map(_.currentValue) 
    tcv.map(_._1) -> tcv.foldLeft(0L)((max, c) => if (max > c._2) max else c._2) 
    } 

    /** 
    * If the predicate cell changes, the Dependent will be notified 
    */ 
    def predicateChanged(which: Cell[_]): Unit = notifyDependents() 
} 

編集:ScalaのCellcovariantではないので、私は私の複数のタイプされた細胞のうち、SeqCellを作ることができなくなりますようにそれはそう。私は本当に任意の数の細胞のためのグローバルな解決に感謝します。

答えて

1

FuncCellを参照してください。 1つまたは複数の他の細胞の機能としてその価値を決定する別の細胞です。私が与えたリンクは、既存のFuncCell1 .. FuncCell5の実装に対応する1-5セルのメソッドを適用するコンパニオンオブジェクトです。これらのセルの1つが値を変更すると、FuncCellは独自の値を更新します。WiringUIをFuncCellに接続します。

そうです場合、changedは今、その値referenceList.filterを呼び出した結果を反映しますCellある

val changed: Cell[List[String]] = FuncCell(length, content){(len,con) => 
    def filter(s: String) = (s.length == len) && (s.contains(con)) 
    referenceList.filter(filter _) 
} 

...私は自分自身を確認してオープンIDEを持っていない、構文エラーを許してください。あなたの編集に対応して


SeqCellについて、私は2つの解決策を考えることができます:

1)を使用すると、既存のFuncCellの実装を使用できるように、タプルに中間セルを結合SeqCell

val cell1: ValueCell[Int] = ... 
val cell2: ValueCell[String] = ... 
val cell3: ValueCell[Stuff] = ... 
... 
val combined: SeqCell[Any] = SeqCell(cell1, cell2, cell3, ...) 
val results = FuncCell(combined){ seq: Seq[Any] => ... } 

2)で型パラメータとしてAnyを使用してください。

+0

あなたのソリューションに感謝しますが、私はこのソリューションを任意の数のセルで使用することはできませんでしたが、SeqCell(cells:Cell [T] *)私はそれをどのように使うのかわかりません(実際に '*'が何を意味するのかわかりませんし、検索エンジンでチェックするのが難しいので) –

+1

'*'はあなたができることを意味します'cells'引数の代わりにカンマ区切りの任意の数の引数を入力します。私はあなたが "varArgs"でより良い検索結果を得るかもしれないと思います。 'SeqCell'の限界は、各セルが同じタイプ(' T')でなければならないということです。それは少し汚いかもしれませんが、あなたはいつでも引数をタプルのセルに凝縮できます。例えば。あなたがCell [A]とCell [B]を持っていれば、それらを 'FuncCell(aCell、bCell){(a、b)=> a-> b}'と組み合わせることができます。 – Dylan

+0

これは、私は自分の問題を解決することができます。しかし、私はあなたが "varArgs"とは何を意味するのか理解していない。あなたは私に例を挙げることができますか? –

関連する問題