ホームページ >ウェブフロントエンド >htmlチュートリアル >申請者ページ??テキスト入力ボックスと単一選択マルチビュー再構築_html/css_WEB-ITnose

申請者ページ??テキスト入力ボックスと単一選択マルチビュー再構築_html/css_WEB-ITnose

WBOY
WBOYオリジナル
2016-06-24 11:56:021133ブラウズ

最近の学校採用シーズンでは、インターンシップ部門が学校採用ソフトウェア サービスを提供していますが、オンライン ユーザーが多く、オンラインに移行するための新機能はあまり多くありません。Ledi は主に再構築を担当しています。今年卒業し、すでに独立して事業開発に取り組むことができる新しい同僚のことを考えてください。 Leti は最近 MVC アーキテクチャについての理解を深め、同僚の Xinsheng からフロントエンドの開発仕様についてもある程度学びました。改めて Xinsheng に感謝したいと思います。教えと無私の援助。

Leti と Xinsheng の最大の違いは、Xinsheng は問題の処理と解決に関して深い理論的基礎を持っていることです。つまり、彼は理由を知っており、単なるプログラマーではなく、独自の思考を持ち、最適化する方法を知っています。コードとパフォーマンス。楽迪は新生から彼の理論体系と問題解決方法を学びました。新生の例で急速に差を縮めます。

この記事で説明するビューは、採用プロジェクトのユニットの応募者機能の下にあります。では、なぜリファクタリングが必要なのでしょうか?

この再構築作業では、次の 2 つの理由があると考えています:

テンプレート内の処理ロジックが複雑すぎる、構造と処理ロジックの分離に準拠していない、コードの可読性が低い高い。
  • 上に示したように、テンプレートは複数の if-else ネストを使用し、さまざまな <% %> を組み合わせて HTML と JS コードを分離しています。性比が低く、改造には適さない。

    同じ種類の複数のビューのロジックと構造にはわずかな違いがありますが、ソース コードには独自のロジックとビューのセットがあり、コードの冗長性が高くなります。後のメンテナンスに役立ちません。

  • Ledi が行った最初のステップは、テンプレートからロジックを抽出し、Beyond Compare ソフトウェアを使用してこれら 3 つのビュー テンプレート (views.SearchItemView1、views.SearchItemView20、views.SearchItemView23) のテキストを比較することでした。テンプレートの違い。ここでの違いには、構造的な違いと論理的な違いの 2 つの部分が含まれます。構造内のタグ名はすべて同じですが、各ビューのタグ属性値は異なります。これらの属性値は、View 内で処理できます。

    Ledi の元の解決策は、各ビューに渡されたモデル値をデバッグすることであり、ビューの構築の違いはモデル値の Ctype 属性にあることがわかりました。


    したがって、上記の 3 つのビューでは、Ctype の判断に基づいて、ビューごとに異なる属性値が構築されます。

    <select data-name="<%=Name%>" data-obj="<%=controlData.Object%>" class="souce_name search_view width130">		<option value="">不限</option>	<%if(typeof searchItems !="undefined"){%>		<%if(searchItems.Value!=null){%>		<%_.each(dataSource, function(item){%>		<%if(searchItems.Value.length>0){%>			<%_.each(searchItems.Value, function(item1){%>								<%if(item1!=item.Value){%>				<option value="<%=item.Value%>"><%=item.Text%></option>				<%}else{%>				<option value="<%=item.Value%>" selected="selected"><%=item.Text%></option>				<%}%>			<%})%>		<%}else{%>		<option value="<%=item.Value%>"><%=item.Text%></option>		<%}%>			<%})%>		<%}else{%>			<%_.each(dataSource, function(item){%>			<option value="<%=item.Value%>" title="<%=item.Text%>"><%=item.Text%></option>			<%})%>			<%}%>	<%}else{%>		<%_.each(dataSource, function(item){%>		<option value="<%=item.Value%>"><%=item.Text%></option>		<%})%>	<%}%></select>
    このコードの隠れた危険性は、モデルに非常に関連する Ctype の判断に基づいてビューが生成されていることです。既存のデータ構造と高度に結合しているため、拡大。このロジックに基づいて、上記の 3 種類のビューと同様の新しいビューを追加する必要がある場合、そのコードに基づいてコードを再度改善し、新しいビューに対して Ctype 判定を追加する必要があります。これは明らかにそうではありません。私たちが欲しいもの。
    再構築の実際の要件は、一般クラスを構築し、各ビューの共通点をこのクラスに書き込み、この一般クラスを異なるサブビューで継承し、相違点がある場合は一般クラスのメソッドをオーバーライドして個別のカスタマイズを実現することです。

    上記の考え方で、次の作業は、前のテキスト比較で得られた差分に基づいてブロック処理を実行することです。つまり、アトミック関数を構築し、どのアトミック ブロックが存在するかを判断し、それらをまとめて一般クラスに書き込むことです。違いはアトミック クラスの空のメソッドの形式に存在し、一般的なクラスの空の関数はサブ関数でオーバーライドされ、パーソナライズされたカスタマイズを実現します。

    textInputAttr:function(){				var isDefault = this.model.get("IsDefault");				var searchItems = this.model.get("searchItems");				var defaultVal  = this.model.get("DefaultVal");				var cType =this.model.get("Ctype");				if(cType==1){					this.$el.find("input[type='text']").addClass("search_box_prev");					this.$el.find("input[type='text']").attr("data-rule-maxlength",300);				}else{					this.$el.find("input[type='text']").addClass("souce_name");					this.$el.find("input[type='text']").attr("data-rule-maxlength",100);					if(cType==23){						this.$el.find("input[type='text']").addClass("default_word");					}				}//针对不同ctype设置input不同属性及值				if(cType==1){					if(typeof isDefault !="undefined"&&isDefault==1)					{						this.$el.find("input[type='text']").attr("defaultValue",defaultVal);					};// 设置defaultValue属性				}								if(typeof searchItems !="undefined")				{					if(searchItems.Value!=null)					{						this.$el.find("input[type='text']").attr("value",searchItems.Value[0]);					}				}				else{					if(cType==1){						if(typeof isDefault !="undefined"&&isDefault==1){						this.$el.find("input[type='text']").attr("value",defaultVal);						}					}									}//设置value属性值			},			checkInputAttr:function(){				var searchItems = this.model.get("searchItems");				var cType =this.model.get("Ctype");				if(cType==1){					this.$el.find("input[type='checkbox']").addClass("search_box_any");				}else{					this.$el.find("input[type='checkbox']").addClass("souce_name");				}					if((typeof searchItems !="undefined")&&(searchItems.Value!=null)&&(searchItems.Value.length>0)){							_.each(searchItems.Value,function(item,value){								var valLength = (cType==1)?(searchItems.Value.length):(searchItems.Value.length-1);//判断采用何种表达式								if(valLength==value){									if(item){										this.$el.find("input[type='checkbox']").attr("value",item);										if(searchItems.Value[value]=="true")											this.$el.find("input[type='checkbox']").attr("checked","checked");									}else{										this.$el.find("input[type='checkbox']").attr("value","");									}								}							});					}else{						this.$el.find("input[type='checkbox']").attr("value","");					}			}//checkbox设置

    一部の論理コードは、異なるビューを持つ異なる変数のみを持ち、親クラスで変数を含むメソッドを構築し、サブクラスで属性値を設定し、それを親クラスのメソッドに渡します。 :

    var SingleInputView = Talent.ItemView.extend({			onBeforeRender:function(){				this.standLabel();//标准化标签			},			onRender:function(){				this.textMaxlen(this.maxlength);				this.setCheckboxVal(this.minus);				this.SetTextInput();				this.SetCheckboxInput();			},			standLabel:function(){				var label = this.model.get("Label");				if((label.length != 7)&&(label.length>6))				{					this.model.set({"Label":label.substring(0,6)+"…"});				}			},			textAddClass:function(){			},			textMaxlen:function(length){				this.$el.find("input[type='text']").attr("data-rule-maxlength",length);			},			setTextDefaultVal:function(){			},			setTextVal:function(){				var isDefault = this.model.get("IsDefault");				var searchItems = this.model.get("searchItems");				var defaultVal  = this.model.get("DefaultVal");				if(typeof searchItems !="undefined")				{					if(searchItems.Value!=null)					{						this.$el.find("input[type='text']").val(searchItems.Value[0]);					}				}			},			checkboxAddClass:function(){			},			setCheckboxVal:function(minus){				var searchItems = this.model.get("searchItems");				if((typeof searchItems !="undefined")&&(searchItems.Value!=null)&&(searchItems.Value.length>0)){							_.each(searchItems.Value,function(item,value){								var valLength =searchItems.Value.length-minus;//判断采用何种表达式								if(valLength==value){									if(item){										this.$el.find("input[type='checkbox']").val(item);										if(searchItems.Value[value]=="true")											this.$el.find("input[type='checkbox']").attr("checked","checked");									}else{										this.$el.find("input[type='checkbox']").val("");									}								}							});					}else{						this.$el.find("input[type='checkbox']").val("");					}			},		});

    一般クラスとサブビュー メソッドを自動的に呼び出すために、親クラスでレンダリング後の onRender コールバック関数を構築しました:

    setCheckboxVal:function(minus){				var searchItems = this.model.get("searchItems");				if((typeof searchItems !="undefined")&&(searchItems.Value!=null)&&(searchItems.Value.length>0)){					_.each(searchItems.Value,function(item,value){						var valLength =searchItems.Value.length-minus;//判断采用何种表达式						if(valLength==value){							if(item){								this.$el.find("input[type='checkbox']").val(item);								if(searchItems.Value[value]=="true")									this.$el.find("input[type='checkbox']").attr("checked","checked");								}else{									this.$el.find("input[type='checkbox']").val("");								}							}					});

    ここで 2 つの this が使用されています .SetTextInput() と this .SetCheckboxInput() の両方のメソッド、それぞれが子クラス内で実行され、異なる子クラス関数を追加実行します:

    onRender:function(){				this.textMaxlen(this.maxlength);				this.setCheckboxVal(this.minus);				this.SetTextInput();				this.SetCheckboxInput();			}

    通用クラス、また一つに使用されますBeforeRender回调方法,用データをテンプレートにレンダリングする前に処理します。

    onBeforeRender:function(){				this.standLabel();//标准化标签			}

        这样处理的优势在于,逻辑更清晰,并且充分利用此回调函数时序上的优势。

        通过对以上重构分析,我们可以得出重构的大体方向:

  • 对差异代码模块化,写入通用类的空方法中。
  • 只有变量差异的代码,写入通用类中带参数方法中。
  • 最后调用方法,写在通用类中,并在子类中,构造定制化加载方法如SetTextInput方法的职能
  • 声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。