2013-02-12 21 views
1

我試圖從摘錄中的Lift Menu.param中提取參數,以便我可以使用它創建命名的Comet。不過,我得到一個NullPointerException當我嘗試參數傳遞給我的Boot.scala使用SnippetDisptach的片段,如這裏建議: http://comments.gmane.org/gmane.comp.web.lift/44299無法從電梯摘要中訪問Menu.param的參數

我創建了菜單項如下:

object AnItemPage { 
// create a parameterized page 
    def menu = Menu.param[Item]("Item", "Item", 
           s => fetchItem(s), item => item._id.toString)/"item" 

    private def fetchItem(s:String) : Box[Item] = synchronized { 
      ItemDAO.findById(ObjectId.massageToObjectId(s)) 
    } 

} 

我已將菜單添加到SiteMap。我也創建了一個片段,我想要拾取Item參數。 (我使用fmpwizard的InsertNamedComet庫在這裏):

class AddCometItemPage(boxedItem: Box[Item]) extends InsertNamedComet with DispatchSnippet{ 
    val item : Item = boxedItem.openOr(null) 
    override lazy val name= "comet_item_" + item._id.toString 
    override lazy val cometClass= "UserItemCometActor" 

    def dispatch = null 
    } 

我的下一個步驟是箱子這個類的一個實例由大衛·波拉克這裏證明: http://comments.gmane.org/gmane.comp.web.lift/44299

這是我已經添加到我的Boot.scala:

LiftRules.snippetDispatch.append { 
    case "item_page" => new AddCometItemPage(AnItemPage.menu.currentValue) 
} 

我item.html引用這個片段:

<div class="lift:item_page"> 

我得到下面的空指針異常,當我編譯和運行這個:

Exception occurred while processing /item/5114eb4044ae953cf863b786 

Message: java.lang.NullPointerException 
net.liftweb.sitemap.Loc$class.siteMap(Loc.scala:147) 
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.siteMap(Menu.scala:170) 
net.liftweb.sitemap.Loc$class.allParams(Loc.scala:123) 
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.allParams(Menu.scala:170) 
net.liftweb.sitemap.Loc$class.net$liftweb$sitemap$Loc$$staticValue(Loc.scala:87) 
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.net$liftweb$sitemap$Loc$$staticValue(Menu.scala:170) 
net.liftweb.sitemap.Loc$$anonfun$paramValue$2.apply(Loc.scala:85) 
net.liftweb.sitemap.Loc$$anonfun$paramValue$2.apply(Loc.scala:85) 
net.liftweb.common.EmptyBox.or(Box.scala:646) 
net.liftweb.sitemap.Loc$class.paramValue(Loc.scala:85) 
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.paramValue(Menu.scala:170) 
net.liftweb.sitemap.Loc$$anonfun$currentValue$3.apply(Loc.scala:114) 
net.liftweb.sitemap.Loc$$anonfun$currentValue$3.apply(Loc.scala:114) 
net.liftweb.common.EmptyBox.or(Box.scala:646) 
net.liftweb.sitemap.Loc$class.currentValue(Loc.scala:114) 
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.currentValue(Menu.scala:170) 
bootstrap.liftweb.Boot$$anonfun$lift$8.apply(Boot.scala:107) 
bootstrap.liftweb.Boot$$anonfun$lift$8.apply(Boot.scala:106) 
net.liftweb.util.NamedPF$$anonfun$applyBox$1.apply(NamedPartialFunction.scala:97) 
net.liftweb.util.NamedPF$$anonfun$applyBox$1.apply(NamedPartialFunction.scala:97) 
net.liftweb.common.Full.map(Box.scala:553) 
net.liftweb.util.NamedPF$.applyBox(NamedPartialFunction.scala:97) 
net.liftweb.http.LiftRules.snippet(LiftRules.scala:711) 
net.liftweb.http.LiftSession$$anonfun$net$liftweb$http$LiftSession$$findSnippetInstance$1.apply(LiftSession.scala:1506) 
net.liftweb.http.LiftSession$$anonfun$net$liftweb$http$LiftSession$$findSnippetInstance$1.apply(LiftSession.scala:1506) 
net.liftweb.common.EmptyBox.or(Box.scala:646) 
net.liftweb.http.LiftSession.net$liftweb$http$LiftSession$$findSnippetInstance(LiftSession.scala:1505) 
net.liftweb.http.LiftSession$$anonfun$locateAndCacheSnippet$1$1$$anonfun$apply$88.apply(LiftSession.scala:1670) 
net.liftweb.http.LiftSession$$anonfun$locateAndCacheSnippet$1$1$$anonfun$apply$88.apply(LiftSession.scala:1669) 

有沒有人,我要去哪裏錯了什麼想法?我一直無法在Menu.param上找到很多信息。

非常感謝您的幫助。

˚F

+0

嘿fin :)你正在運行哪個版本的Lift/Scala? 2.4或2.9或2.5-SNAPSHOT 2.10或類似的東西? :) – 2013-02-13 06:24:44

+0

嗨弗蘭茲。我使用升降機2.5-M2使用Scala 2.9.1。非常感謝您看這個! – fin 2013-02-13 12:38:12

+0

嗯,這種行爲真的很奇怪。您是否嘗試過升降谷歌組?我的猜測是這是一個錯誤,但請在開題之前先在小組中提問。可悲的是我的電梯網絡端口還遠遠不夠測試它。 :) – 2013-02-13 19:05:40

回答

3

我從來沒有嘗試過自己在做什麼,所以我不知道來完成它的最佳方式。您使用Loc Param的方式是從URL模式中提取變量。在你的情況下,http://server/item/ITEMID其中ITEMID是一個Item的字符串表示形式,它是傳遞給fetchItem函數的值。如果您只是隨意調用函數調用,函數調用將沒有值,並且從我所看到的您請求的值未初始化。

我認爲有兩種可能的解決方案。第一個將使用S.location而不是AnItemPage.menu.currentValue。它將返回代表當前正在訪問的LocBox[Loc[Any]](使用參數設置)。您可以使用該Loc來檢索currentValue並設置您的參數。

另一種選擇是在您的代碼段中實例化actor。事情是這樣的:

item.html

<div data-lift="AnItemPage"> 
    <div id="mycomet"></div> 
    </div> 

,然後在AnItemPage片段,像這樣:

class AnItemPage(item: Item) { 
    def render = "#mycomet" #> new AddCometItemPage(item).render 
} 

我沒有測試過這類原因,因此他們可能需要一些調整。希望它會給你一個大概的想法。

+0

謝謝jcern。我已經嘗試了上面的第二個想法,但不幸的是我無法將一個Item對象傳遞給片段。我現在會測試你的第一個建議。 – fin 2013-02-13 19:22:50

+0

我不確定我明白你爲什麼不能通過一個項目的片段?一般來說,這將通過電梯來處理。 Lift會使用構造函數來查找片段,該構造函數接受從URL中提取的對象。我認爲您正在建模的示例的完整代碼可在此處參考:https://github.com/dpp/simply_lift/tree/master/samples/shopwithme/src/main/webapp,它有一個完整的示例。 – jcern 2013-02-13 22:19:37

+0

將項目傳遞給片段。我認爲我最初的問題是我沒有註冊SiteMap的菜單。謝謝。 – fin 2013-02-17 13:31:48