4

警告: 問題の問題に関する情報がたくさんあるため、これは長文です。準備を整えてください。時間を割いて読んでくれたことに感謝します。

私はクライアント用の非常に大きな WebApp を書いている最中であり、jQuery を使用してこのための多数のインタラクティブなアプリケーションを構築しましたが、私が開発したものには疑問が残りました:これを行う標準的な方法はありますか、それとも単により良い方法

私は常に最適なアプリケーションを構築することを目指しているので、これを行う特定の方法があるかどうかについての洞察を得るために、皆さんのところに来ました。

完了しなければならなかったタスク

私が構築しているアプリでは、ユーザーが製品の請求書を作成できる必要があります。この請求書には、検索ボックスを使用して任意の数の製品を追加できます。各製品はデータベースから取得され、その検索ボックス内に保存され、各製品は複数回追加できます。

ユーザーが製品を追加する方法は、検索ボックスに製品の名前を入力し、 [製品の追加] ボタンを押すことです。これにより、処理されたテンプレートが製品リストの先頭に追加されます。かなり単純ですよね?

問題

私が遭遇した大きな問題は、請求書に製品のリストを含めることができるだけでなく、これらの製品のそれぞれにさまざまなカスタマイズ可能な詳細が含まれていたことです。つまり、各製品には独自のフィールドがいくつかあり、ユーザーはそれらを編集して多くの変更を加えることができました。たとえば、あるタイプの製品には数量があり、合計価格を返すにはその製品の原価を掛ける必要があります。別の製品にはlengthがあり、これにwidthを掛ける必要があります。次に、その製品の原価を掛けて合計価格を返す必要があります。

ご想像のとおり、さまざまな種類の製品があり、多くの異なるフィールドがあり、さまざまな計算が行われます。作成の最後に、ユーザーが追加できる完全な変更可能性を維持しながら、PHP ページに解析する必要があります。飛び回ることなく、同じ請求書ページで製品を削除/編集します。

これは、私にとっては悪夢でした。これをクリーンに保ち、さまざまな入力/jQuery オブジェクトが何らかの形で互いに衝突しないようにする方法が必要だったからです。また、データベースから情報を取得するものがあるため、読み込まれた製品と新しく作成された製品を区別する必要がありました

私が構築したソリューション

そのため、製品がリストの先頭に追加されると、製品には多数のフィールド、多数の詳細、および削除ボタンが含まれます。最初に行ったのは、さまざまな種類の製品ごとに交換可能なトークンを使用してテンプレートを作成することでした。それは簡単で、完全にうまくいきました。製品がリストの前に追加されたとき、その製品に関連するすべての要素に、ハンドラーを追加できるようにrel属性を追加しました (これを「フック」と呼びました)。その特定のフックで要素のみを変更しました

入力には、 の形式で入力配列を使用しました<input name="Products[%HOOK%][%PRODUCTDATAKEY%]" value="%PRODUCTDATAVALUE%" />。私の主な問題が発生した場所は、データベースに既に保存されているロードされた製品と、追加されたばかりの新しく追加された製品を区別する必要がある場所でした。私がこれを行った方法は、すべての入力名配列の前に [Loaded] を追加して、PHP スクリプトが [Loaded] 配列を個別に処理できるようにすることでした。

私の懸念は何ですか?

私の最大の懸念は、マークアップからコードに至るまで、すべてがいかに乱雑に見えるかということです。フックがいたるところに飛んでいる非常に長い入力名数千行のコードと、さまざまなキーとトークンを交換するという頭痛の種. それは完全に問題なく動作しますが、開発者として見ると恐ろしいと感じます. この「追加された製品」を例にとります。

<div class="item product special-order" rel="7" style="">
    <input type="hidden" name="products[7][id]" value="17">
    <input type="hidden" name="products[7][item_id]" value="">
    <input type="hidden" name="products[7][type]" value="Special Order Flooring">
    <input type="hidden" name="retail_price" class="invoice-base-cost" value="18.49">
    <h4>Carpet Brand<a name="action" rel="7" class="btn btn-mini btn-danger remove-product initialized" style=""><i class="icon-remove"></i> Remove</a>
 </h4>
    <div class="item-details">
        <div class="detail-column">
            <div class="detail">
                <span class="detail-label detail-label-medium"> Type:</span>Carpet
            </div>
            <div class="detail">
                <span class="detail-label detail-label-medium">Range:</span> Carpet Brand
            </div>
            <div class="detail">
            <span class="detail-label detail-label-medium">
                Colour:</span><input required="" class="detail-input-large left-align" value="" type="text" name="products[7][colour]">
            </div>
            <div class="detail">
            <span class="detail-label detail-label-medium">
            Length:</span><input type="text" name="products[7][length]" rel="7" class="length-field initialized" placeholder="Enter the length..." value="1.000"><span class="detail-unit">m</span>
            </div>
        </div>

        <div class="detail-column">
            <div class="detail">
                <span class="detail-label detail-label-large">Manufacturer:</span>
                <select class="detail-input-large" required="" name="products[7][manufacturer_id]">
                    <option value="14">Manufacturer 1</option>
                    <option value="16">Manufacturer 2</option>
                </select>
            </div>
            <div class="detail">
                <span class="detail-label detail-label-large">Width supplied:</span><input type="text" name="products[7][width]" class="width-field" value="5.000"><span class="detail-unit">m</span>
            </div>
            <div class="detail">
                <span class="detail-label detail-label-large">Retail price per/m:</span> £18.49
            </div>
            <div class="detail">
                <span class="detail-label detail-label-large">Room:</span><input class="detail-input-large left-align" type="text" name="products[7][room]" value="" required="required">
            </div>
        </div>
        <div class="item-cost">
            <h5>Item cost</h5>
            £<span class="invoice-cost" rel="7">92.45</span>
        </div>
    </div>
</div>

それはやり過ぎではありませんか?これらをJSONオブジェクトにマップして、どうにかしてもっときれいにすることはできなかったでしょうか? または、これはこれを行う正しい方法ですか?

その製品には、約5 つの異なるイベント バインドもありました。これは、長さフィールドが変更された場合、幅と基本価格によって価格を再計算する必要があり、幅を少し後ろに戻して再計算する必要があったため、面倒でした。これはすべて、同じ rel (フック) を持つフィールドを検索することによって行われました。これにどのようにアプローチすべきかについて、専門家の意見を得ることができれば幸いです。

4

3 に答える 3

3

spez86 が示唆したように; フレームワークを使用して HTML を生成し、各 HTML セクション内に存在する要素にイベントをバインドする必要があります。backbonejshandlebarsjsをご覧になることをお勧めします。これら 2 つを組み合わせて使用​​すると、目的を達成するために最小限の労力を費やすだけで済みます。使い方の詳細については、
次のURLを参照してください。
最初に UI で作業することをお勧めします。つまり、さまざまな種類の製品に対して個別のテンプレートを作成し、[製品を追加] ボタンをクリックして、バックボーン ビューを製品リスト コンテナに追加してみてください。
HTML をページに正常に追加できたら、製品テンプレート内にある子要素にイベントをバインドすることができます。eventsこれは、Backbone.View クラスの関数内で実行できます。ここに登録されたイベント ハンドラーは、このビュー内に存在する要素にのみ関連付けられ、同じ CSS クラスを持つページ DOM 内に存在する他の要素には関連付けられません。[rel]したがって、メカニズムと長い入力名を取り除くことができます。これが少し役立つことを願っています。

于 2013-08-27T13:42:07.287 に答える
2

正直なところ、あなたが話しているデータの量とそれを変更する方法の数を考えると、より堅牢で、データ バインディングをより簡単にするように設計されたフレームワークを検討する必要があります。たくさんありますが、私の個人的なお気に入りは AngularJS です。

http://angularjs.org/

アプリの開発とその後のメンテナンスに多くの時間を節約できる可能性があるため、これを調べ始めてください。

于 2013-08-23T15:18:45.443 に答える