最近、Yu おじさんが書いた「フロントエンド UI コンポーネントを構築するための新しいアイデア」という記事を読んで、昨年シェアした記事「感情を伴う共同開発のための JS デザイン パターン」を思い出しました。少し共鳴しました。 。
昨年の Alipay のレジプロジェクトの新バージョンでは、このコンポーネント コーディング モデルをしばらく試したと言われていますが、ここで少し経験を共有します。
前述の抽象クラスを振り返ると、デザイン パターンについてある程度知っている学生には馴染みがあるかもしれません。一見、抽象ファクトリーのように見えますが、次の基本クラスと組み合わせると、オーバーライドしていないことがわかります。 getVessel、show、hideなどのメソッドは各基本クラスにありますが、抽象クラスではこれらのメソッドを直接継承しています。なぜこんなことをするのか理解できない人もきっといるでしょう。JAVAではなくJSだからです。私の意見では、十分な柔軟性と引き換えにある程度の結合は過剰ではありません。言うまでもなく、この抽象クラスは、作成後に自由に変更できないようにする必要があります。
この抽象クラスを通じて、連絡先オブジェクトをコンテナ オブジェクトに関連付け、アクション メソッドを通じてそれらの間の最も単純な対話を実装します。 「最も単純」とは単に表示または非表示の操作を意味するので、show メソッドと Hide メソッドを定義しました。明らかに、「最も単純な」インタラクション動作ではユーザーの動作を 100% 満たすことはできないため、setInterface メソッドを設定し、特別なインタラクション効果を必要とするクラスにエフェクト クラスを追加する必要があります。最後に、この抽象クラスを使用する場合は、直接インスタンス化することは避けてください。操作をインスタンス化する場合は、特定の継承クラスに移動してアクション メソッドをオーバーライドする必要があることをアクション メソッドの全員に思い出してください。
この抽象クラスを通じて、最も基本的な aPop、dropDown、xbox、xTab およびその他のコンポーネントを継承できます。これらについては、以前の記事ですでに説明しましたので、ここでは詳しく説明しません。ここに書かれた基本クラスでは特殊なニーズを満たせない場合、パーソナライズされたコンポーネントを迅速に開発するにはどうすればよいでしょうか。
xTab を例として考えてみましょう。このコンポーネントを使用して、マルチタッチ ポイントと複数のコンテナの間の基本的な切り替え効果を完成させることができます。しかし、これにアニメーション効果を追加する必要がある場合はどうすればよいでしょうか。まず、継承されたクラス タブの実装コードを見てみましょう。
show メソッドの後に setInterface メソッドを実行したことがわかります。このインターフェイス メソッドは、同様のインタラクティブ ラインに追加のインタラクティブ エフェクト クラスを追加するように設計されています。たとえば、ここでは slideTab の効果を扱いたいと考えています。その場合は、xTab に基づいてアプリケーション クラスを継承し、setInterface メソッドをオーバーライドし、アニメーション クラスを追加してスライド効果を実現するだけです。これで完了です。
AP.widget.animTab = AP.widget.xTab.extend({
setInterface:function(ターゲット,容器){
this.parent(ターゲット,容器);
this.anim(容器);
}、
anim:関数(容器){
...
}
});
正直に言うと、これは非常に大雑把な設計アイデアですが、これにより、コンポーネントのコーディング モードを別の角度から考えることができます。上記はほんの表面的なアプリケーションの試みであり、興奮は続きます...お待ちしています。
転載: http://ued.alipay.com/2010/06/proused-front-end-ui-components-and-then-build-a-new-train-of-thought/
AP.widget.xTab = AP.widget.basic.extend({
bindEvents:function(ターゲット,容器){
E.on(target,this.options.eventType,this.action,target,this);
E.on(window,'load',this.oXtab,target,this);
}、
アクション:関数(e,ターゲット){
this.switchTab(e,target);
}、
switchTab:function(e,target){
...
for(i=0,len=tabs.length;i<len;i++){
var hash = tabs[i].href.split("#")[1];
var容器 = D.get(ハッシュ + '拡張');
if(容器){
this.hide(容器);
}
D.removeClass(tabs[i].parentNode,'current');
if(target.href == tabs[i].href){
D.addClass(target.parentNode,'current');
if(容器){
this.show(容器);
}
//各種アプリケーションインターフェースの設定
this.setInterface(ターゲット,容器);
}
E.preventDefault(e);
}
}、
showTab:関数(インデックス){
...
}、
//位置決めタブを初期化する
oXtab:function(target,e){
...
}
});
AP.widget.basic = 新しい AP.Class({
setOptions:function(オプション){
//インターフェースの設定
}、
初期化:関数(ターゲット,オプション){
//初期化メソッド。目的は、ターゲットのサブセット要素とメソッド間の関連付けを確立することです。
}、
getVessel:function(ターゲット){
//ターゲットのマッピング関係を満たすコンテナを取得
}、
bindEvents:function(ターゲット,容器){
//ターゲットのトリガーアクションをここにバインドします
}、
アクション:関数(){
//ターゲットにバインドされたイベントによってトリガーされる実行関数には、実行するロジックが含まれています。
}、
show:function(){
//コンテナを表示する
}、
隠す:function(){
//コンテナを非表示にする
}、
setInterface:function(){
//各コンポーネントが共有するインターフェースを設定
}
})