2016-11-02 56 views
1

我厭倦了寫作blah: "${JSON.stringify(target)}"當我處理我的DTO對象時,我只想寫blah: "$target"如何覆蓋JS對象的toString()方法以使用JSON.stringify()?

我的DTO的樣子:

@js.native 
trait AuthConnectionDetails extends js.Object { 
    def clientId: String = js.native 
    def accountHostname: String = js.native 
} 

這些DTO的用於分析一些REST API調用的內容,如:

val response = js.JSON.parse(xmlHttpRequest.responseText). 
    asInstanceOf[AuthConnectionDetails] 

我不介意改變我如何定義我的DTO對象來做到這一點(也許我應該爲我的DTO或類似的東西使用case類,而不是原生的js特徵?),但我無法弄清楚如何去做。

我試着寫了一個特性,我可以混入,但沒有工作,我試着寫一個隱式擴展方法,但那也沒有工作。

我隱碼似乎並沒有爲工作的toString:

object JsonToString { 
    implicit class JsObjectExtensions(val target: js.Object) extends AnyVal { 
    override def toString:String = JSON.stringify(target) 
    def json:String = JSON.stringify(target) 
    } 
} 

所以我可以做blah: "${target.json}",哪個更好 - 但我特別想擺脫那些括號。

有什麼辦法可以用scala.js來做到這一點嗎?

回答

2

不,沒有辦法做到這一點。這是因爲字符串插值將始終使用對象本身的toString()方法,無論在其類型或隱式類別中如何聲明(這是一般的Scala事物)。

你可以做到這一點的唯一方法就是在每次創建一個方法時,通過用自定義的toString()方法修補它們來修改對象。這包括當你從JSON字符串中解析它們時。我敢肯定,當你將它們串起來時,會比撥打.json更糟糕。

2

如果你真的想,你可以寫你的自定義字符串插值:

implicit class JsonHelper(private val sc: StringContext) extends AnyVal { 
    def dejson(args: Any*): JSONObject = { 
    sc.checkLengths(args) 
    s(args.map(jsonify)) 
    } 

    private def jsonify(arg: Any) = arg match { 
    case obj: js.Object => JSON.stringify(obj) 
    case _ => arg.toString 
    } 
} 

現在你可以使用這個像這樣:

dejson"hello: $target, world: $target2"