هل هذه الطريقة الصحيحة للتعامل مع رابط الرفع في إطار الرفع؟

StackOverflow https://stackoverflow.com/questions/2036037

  •  19-09-2019
  •  | 
  •  

سؤال

إذا كان لدي عنوان URL مثل http: // localhost / اختبار / تحرير /{ID} وأود أن تحويل {ID} إلى معلمة بدلا من جزء مسار URL.

هل هي أفضل طريقة للقيام بذلك عن طريق إنشاء قائمة مع rewriterequest؟ لأنني وجدت أنه يضغف قليلا إذا كان لدي نمط URL الكثير مثل هذا.

val menu = Menu(new Loc[Unit] {

    override def name = "Test"
    override def text = "Test"
    override def link = (List ("Test"), true)
    override def params = Nil
    override def defaultValue = Full(())


    def isTarget (path: ParsePath) = path match {
        case ParsePath (List("Test", "edit", id), _, _, _) => true

        case _ => false
    }

    override def rewrite = Full ( NamedPF("Test") {
        case RewriteRequest (path, _, _) if isTarget(path) => 
             RewriteResponse(List("Test", "edit"),  
                             Map("id" -> "1024")) -> ()

    })
})
هل كانت مفيدة؟

المحلول

في Boot.Scala تحتاج إلى ما يلي (من رمز العمل الفعلي!) لاحظ أن كل مسار إعادة توجيه يجب أن يكون في خريطة الموقع الخاص بك.

LiftRules.rewrite.append {
  case RewriteRequest(ParsePath(List("shopInfo", "view", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "view" :: Nil, Map("id" -> id))
  case RewriteRequest(ParsePath(List("shopInfo", "orders", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "orders" :: Nil, Map("id" -> id))
  case RewriteRequest(ParsePath(List("shopInfo", "sync", id), _, _, _), _, _) => RewriteResponse("shopInfo" ::  "sync" :: Nil, Map("id" -> id))
  case RewriteRequest(ParsePath(List("shopInfo", "delete", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "delete" :: Nil, Map("id" -> id))
  case RewriteRequest(ParsePath(List("shopInfo", "edit", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "edit" :: Nil, Map("id" -> id))
}

نصائح أخرى

شكرا لجميع الردود الخاصة بك.

ما أريده أكثر هو أن هذه الأشياء إعادة الكتابة مجتمعة بإحكام مع القائمة، لذلك يمكنني إعدادها فقط في فئة النموذج الخاصة بي، مثل تحطم هذه السمة.

في النهاية، قمت بإنشاء فئة فرعية من LOC نفسي للتعامل مع قواعد إعادة الكتابة هذه، ووجدت أنها تعمل بشكل جيد وجعل الأمور أكثر بساطة (على الأقل بالنسبة لي)، لذلك أقوم بنشر الكود هنا.

لا تتردد في نسخ هذا إذا احتاج أي شخص

/**
 *  A RESTful-like URL handling Loc
 *
 *  If you have the following templates:
 *
 *    * webapps/item/edit.html
 *    * webapps/item/view.html
 *  
 *  You want the following URL map to corresponding template with 
 *  last path component as a S parameter.
 *
 *    http://localhost/item/edit/1  to  http://localhost/item/edit
 *    http://localhost/item/view/1  to  http://localhost/item/view
 *
 *  You could create a Menu with this Loc class in your Model object.
 *
 *  <code>
 *  object Item extends Item with LongKeyedMetaMapper[Item] 
 *  {
 *      // Other methods here...
 *
 *      def menu () {  
 *
 *          // What methods do we have?
 *          val methods = List ("view", "edit")
 *
 *          val parameterName = "itemID"
 *          val itemLoc = new RESTfulLoc("Item", List("item"), "Item", 
 *                                       methods, parameterName)
 *
 *          Menu (itemLoc)
 *      }
 *  }
 *  </code>
 *
 *  Now add the menu to SiteMap in Boot.boot
 *
 *  <code>
 *  class Boot {
 *      def boot () {
 *          
 *          val entries = Item.menu ::  Nil
 *
 *          LiftRules.setSiteMap(SiteMap(entries:_*))
 *      }
 *  }
 *  </code>
 *
 *
 *  Finally, You could access the parameter in your snippet with 
 *  S.param("itemID")
 *
 */
class RESTfulLoc (val name: String, val path: List[String],
                  val text: LinkText[Unit], val methods: List[String],
                  val parameterName: String,
                  val locParams: LocParam[Unit]*) extends Loc[Unit] 
{
    override val defaultValue = Full(())
    override val params = locParams.toList
    override val link: Link[Unit] = (List(path.first), true)

    def this (name: String, path: List[String], text: LinkText[Unit], 
              methods: List[String], locParams: LocParam[Unit]*) = 
    {
        this (name, path, text, methods, "id", locParams:_*)
    }

    private def isTarget (path: ParsePath) = 
    {
        path.partPath -- this.path match {
            case List (action, id) => {
                (methods contains action) && id != "index"
            }
            case _ => false
        }
    }

    override def rewrite = Full (NamedPF("RESTfulLoc") 
    {
        case RewriteRequest (path, _, _) if isTarget(path) => {
             val parameter = path.partPath.last
             val action    = path.partPath.init
             val data      = Map (parameterName -> parameter)

             RewriteResponse(action, data) -> ()
        }
    })
}

لقد تعثرت على هذا المنصب لأنني كان لدي نفس السؤال. الجواب من Jim Barows صحيح (وأسهل)، ولكن دون أي تفسير كان من الصعب بالنسبة لي أن أفعل ما يفعله هذا الرمز. شرح مفصل لماذا يمكن العثور على أعمال حل Jim في كتاب الرفع عبر الإنترنت (http://groups.google.com/group/the-lift-book.). تحقق من القسم 3.12، بعنوان "إعادة كتابة عنوان URL" الذي يمشي لك من خلال خطوة بخطوة حول كيفية إنشاء عنوان URL مريح.

على أي حال، يجب ألا تكون هناك حاجة لكتابة LOC مخصص لتحقيق التأثير المرغوب فيه.

حظا سعيدا

آسف، التعليق أعلاه هو كلي فوضوي.

المشكلة هي أنه إذا كان لدي قالب اسمه Edit.html ضمن WebApp / Test، وهو القالب الذي استخدمه لتحرير عنصر.

ولدي مثيل قائمة مثل ما يلي:

Menu (Loc("Test", List("Test") -> true, "Test"))

سوف تطابق عنوان URL فقط http: // localhost / اختبار / تحرير, ، ليس أي شيء مثل http: // localhost / اختبار / تحرير / 1

لماذا تريد تغييره للاستعلام عن Param؟ هل هو لأسباب تقنية أو إطارية؟

ينتمي {ID} في رأيي إلى مسار URI، وهو يحدد مورد فريد من نوعه وأحب الحفاظ على هذه المعلومات داخل المسار. يمكن أن يكون URIS أي نوع من سلسلة الأحرف (لذلك فإن معلمة الاستعلام ستؤدي أيضا)، لكنني سأصمم URIS كمتواصل بموارد وثيق مطابقة قدر الإمكان.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top