1

Lift を使用して画像をアップロードし、リロードせずにページの一部の要素にすぐに表示したいと考えています。このソリューション(PHPを使用)のようにやりたいです。

プロセスは比較的簡単です。PHP ファイルをダミーの HTML スニペットに置き換えました。

<form id="imageform" method="post" enctype="multipart/form-data" action="ajaximage.html">
    <input id="imageFile" name="imageFile" type="file" size="50" maxlength="100000"/>
</form><br/>

<script src="jquery-1.8.3.min.js"></script>
<script src="jquery.form.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        $('#imageFile').live('change', function() {
            $("#preview").html('');
            $("#preview").html('<img src="images/processing.jpg" alt="Uploading...."/>');
            $("#imageform").ajaxForm({
                target : '#preview'
            }).submit();
        });
    });
</script>

HTML スニペット:

<img src="images/someimage.jpg"/>

まあ、これはうまくいきます。しかし、明らかに動的な動作が必要です。サンプル ページでは、HTML スニペットの代わりに PHP ファイルを使用しています。このファイルは、リクエストからデータを抽出し、サーバーに保存し、それに応じてプレビュー イメージの HTML を出力します。echo "<img src='uploads/".$actual_image_name."' class='preview'>";

さて、リフトでこれを達成する方法がわかりません。

このディスカッションを見つけました: https://groups.google.com/forum/?fromgroups=#!topic/liftweb/6bxNlbBPJvEしかし、フレームワークと使用したくない HTML5 に関する漠然としたアドバイス以外に、良い解決策はありません。 .


パート 2。私は、Lift でこのためのいくつかの基本を既に実装しています。

HTML:

<div class="lift:AddImage.addEntry" form="POST" multipart="true">
        <p><prefix:imageUpload/></p>
        <p><prefix:test/></p>
</div>

スニペット:

package code 
package snippet

import net.liftweb.http.S
import net.liftweb.common.Full
import net.liftweb.common.Empty
import net.liftweb.common.Box
import net.liftweb.http.FileParamHolder
import net.liftweb.util._
import Helpers._
import scala.xml.Group
import scala.xml.NodeSeq
import net.liftweb.http.SHtml
import javax.annotation.Resource
import java.io.OutputStream
import java.io.FileOutputStream

class AddImage {

  // Add a variable to hold the FileParamHolder on submission
  var fileHolder : Box[FileParamHolder] = Empty

  def submitTest () {
    println("submitTest called!")

    val receiptOk = fileHolder match {
      // An empty upload gets reported with a null mime type,
      // so we need to handle this special case
      case Full(FileParamHolder(_, null, _, _)) => true

      case Full(FileParamHolder(_, mime, _, data)) =>

        println("MIME: " + mime)

        if (mime.startsWith("image/")) {

            println("uploading the image: ")

            //scala.io.Source.fromBytes(data)
            try {
                val out: OutputStream = new FileOutputStream("test.jpg");
                out.write(data);
                out.flush();
                out.close();

            } catch {
              case e: Exception => println("Exception!: " + e)
            }

          true
        }

      case Full(_) => {
        S.error("Invalid attachment")
        false
      }

      case _ => true
    }

//    (e.validate, receiptOk) match {
//    }
}

  def addEntry(content: NodeSeq): NodeSeq = {

      bind("prefix", content,
              "imageUpload" -> SHtml.fileUpload(f => fileHolder = Box !! f),
              "test" -> SHtml.submit("submitz", submitTest))
  }
}

しかし、私はここで立ち往生しています:

  • Liftで作成したフォームをjqueryから参照する方法がわかりません。

  • JavaScript は、アップロード入力フィールドが変更されたときにフォームを送信しajaxForm()、PHP スクリプトの結果を#preview要素に挿入します。フォームをscalaで送信し、さらに画像HTMLを出力して、挿入できるようにする方法がわかりません#preview

これが多くの質問ではないことを願っています:)事前に感謝します。

4

1 に答える 1

1

これは、質問に対処するのに役立つはずの一連のポインターほど完全な答えではありません。

JS をフォームにアタッチするには、フォームに id 属性を追加して、そのようにアタッチできるはずだと思います。何らかの理由でそれがうまくいかない場合は、次のようにフォームを div でラップするのが簡単な回避策です。

<div id="wrapper"><form> ... </form></div>

そして、次のような jquery でそれを取得できます$('#wrapper form')https://www.assembla.com/spaces/liftweb/wiki/AJAX_File_Uploadに ajax ファイルのアップロードと Lift に関する wiki 記事があります。また、フォームの送信をリダイレクトするために jQuery メソッドを使用しているため、そこから洞察が得られるかもしれません。

画像データを実際に表示する場合、いくつかの便利な機能があります。最初はJsCmds.SetHtmlで、もう 1 つは ですS.fmapFunc

を使用JsCmds.SetHtml(id:String, replacement:NodeSeq)すると、特定の ID に一致する html 要素の内容を、指定された に置き換えることができますNodeSeq

を使用S.fmapFuncすると、画像を返す関数を作成できます。以下の例では、画像をバイト配列に読み取り、それをブラウザに出力する関数を作成します。これには一意の ID が与えられます。2 番目の部分は、一意の ID を参照し、それに対して何かを行うオブジェクト (この場合は XML 要素) を返します。したがって、以下の例は、イメージを呼び出すイメージ タグを返します。

   S.fmapFunc(() => {
       val mimeType:String = //set mimeType
       val data:Array[Byte] = //get byte array of image
       throw ResponseShortcutException.shortcutResponse(
           InMemoryResponse(data, 
              ("Content-Type" -> mimeType) :: Nil, Nil, 200))
   }) { 
       name => <img src={"?" + name + "=_"} />
   }

これは を使用してInMemoryResponseいますが、画像の大きさによっては理想的ではない場合があります。も使えStreamingResponseます。

この 2 つを一緒に使用すると、ページに表示できる画像へのリンクを含む Html を生成する必要があります。これを行うにはおそらく多くの方法があるので、間違いなく、必要なものを機能させることができるでしょう。Ajax ファイルのアップロードは少しトリッキーな場合があるため、すべてを連携させるには多少の作業が必要になる場合がありますが、これで正しい方向に進むことができれば幸いです。

また、補足として、リフトに関する質問の最も活発な場所は、彼らのメーリング リストである liftweb@googlegroups.com です。プロジェクトのコミッターを含め、多くの人がそれを監視しており、彼らは非常に反応が良いです。

于 2012-12-26T15:11:12.857 に答える