2013-02-12 55 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