(与此主题没有紧密关联但声明用例。可跳过)
我正在使用addRowHandlers()
来编写React代码。我现在有一个...
reader.onload = function() {
// (create table rows...)
addRowHandlers(); // now there are rows to select :)
}
,其中包含一堆Scala.js
个,每个都需要一个form
的道具。请参阅Controlled component。
input
问题是:onChange callback
与case class Input(info:String,value:String,onChange:(e:Event)=>Unit)
无关,但与之相关。我会将控制逻辑与Web内容分开。所以我做了:
info
这只解决了耦合问题的一半。因为React
的实现必须在React组件内部写入访问状态。 trait Control[T]{val value:T,val onChange:(e:Event)=>Unit}
case class Input(info:String)
//when need to create a controlled props:
private trait TextInputCtrl extends Control[String]{//..implementation}
new Input("some info") with TextInputCtrl
也一样,除非公开TextInputCtrl
。但如果你这样做,你可以在外面运行React逻辑。
好。 如果可以将trait动态混合到实例中。我可以在其他地方创建一个不受控制的干净new Input(...)
实例,并将其传递给React组件。更加灵活。这甚至提供了杠杆作用:
TextInputCtrl
所以,我做了一些尝试:
我想用这个简单的哲学:
Input
但是通过宏:
Seq(input...).map(_ with XXControl)
我成功编译了。但在运行时失败了:
def dynamix(in:Input):Input with Control{
new Input(in.info) with Control{//..implementation}
}
它抛出:
q"""
new $MixinToolSym[$tpeC,$tpeT]{
def dynamix(in: $tpeC): $tpeC with $tpeT = {
new $tpeC (..$constrBody) with $tpeT
}
}
"""
有什么问题?
这不是trait MixinTool[C, T] {
def dynamix(in: C): C with T
}
object MixinTool {
implicit def materialize[C, T]: MixinTool[C, T] = macro MacroImpl.impl[C, T]
}
val mt=MixinTool.materialize[Input,Control]
mt.dynamix(inputInstance) //error
的问题。
=============================================== ====
其他方法: (但可能不是最佳解决方案)
以下两者都失去了自我类型特征直接访问其他领域的能力。并且难以逐步链接或部分覆盖控制逻辑。
java.lang.IllegalAccessError:
tried to access field x.x.Input.info from class x.x.X$$anon$3$$anon$2
或:
scala App