2

HTML 要素に密接に関連する JavaScript で、クリーンなオブジェクト指向コードを構築しようとしています。

私が解決しようとしている状況は、複数の提案が与えられているページです。すべての提案にはいくつかのオプションがあり、すべてのオプションにはそれをアクティブにするためのボタンがあります。HTML の簡略化されたスニペットは次のようになります。

<div class="row suggestion">
    <div class="span6">
        <ul>
            <li data-id="1">
                <span>Option 1</span>
                <span><a class="btn btn-mini" href="#">pick me</a></span>
            </li>
            <li data-id="2">
                <span>Option 2</span>
                <span><a class="btn btn-mini" href="#">pick me</a></span>
            </li>
        </ul>
    </div>
    <div class="span6">
       <button>Save</button>
    </div>
</div>

オブジェクトを使用せずにこれをスクリプト化する方法は知っていますが、提案に機能を追加したいので、クリーンな OO アプローチを採用したいと考えています。OO の利点を知っていて、私の選択を選んでください。

これまでに試したことは次のようになります。

$(document).ready(function(){
    var suggestions = [];

    $('.row.suggestion').each(function(){
        suggestions.push(
            new Suggestion($(this))
        );
    });
});

function Suggestion($el){
    var options = new Array();

    $el.find('a').each(function(){
        options.push(new Button($(this)));
    })
}
Suggestion.prototype = {
    childChange : function(){
        // do some checks;
    }
}

function Button($el){
    this.$el = $el;
    this.id = $el.parents('li').data('id');
    $el.click(this.onclick);
}
Button.prototype = {
    checked : false,
    $el : null,
    id : 0,
    onclick : function(){
        // set this button active
        // notify my parent suggestion that i've changed
    }
}

onclick 関数までは期待どおりに動作します。トリガーされると、関数は開始されますが、スコープが変更されます。オブジェクトにアクセスできると思っていましたが、クリックした要素の jQuery インスタンスのスコープに制限されています。

私はいくつかのアイデアを持っていましたが、それらにはすべて注意事項がありました。

  • 特定のDOM要素にすべての属性と機能を追加しましたが、そのOOを行う方法がわかりませんでした
  • 要素に属性を追加するために jquery.data() を使用します。しかし、関数をjqueryインスタンスに追加する方法がわかりませんでした。
  • Prototype、YUI3、または特定のデザイン パターンなどの別のライブラリを使用します。だから私は読み始めました:

この瞬間まで、ページ上の要素に密接に関連する JavaScript のオブジェクト指向プログラミングに対する既知の解決策を見つけることができません。私が見つけたすべての OO JS の例には、出発点として要素がありません。すべての提案を歓迎します。

4

2 に答える 2

1

まず第一に、よりメンテナンスしやすい OO パターンを選びます。

次に、要素に関連付けるには、それらをインスタンス プロパティにするだけです。

var myApp = {};
myApp.dom = {};
myApp.dom.Suggestion = function(options) {
   this.container = document.createElement("option");
   this.options = [];
   for (var i = 0, len = options.length; i < len; i++) {
       this.options[i] = document.createElement("option");
       this.options[i].setAttribute("value", options[i]);
       this.options[i].addEventListener("change", this.change.bind(this), false);
       this.container.appendChild(this.options[i]);
   };
};
// now you already have two properties, the suggestion container and the options.
myApp.dom.Suggestion.prototype.change = function(event) {
    var currentOption = event.target;
};
myApp.dom.Suggestion.prototype.decorateElement = function(parent) {
   try {
      parent.appendChild(this.container);
   } catch (DOMException) {
      console.log("Specify a parent element");
   };
};
// now you have instance references to all your properties.

本当に必要なのは、要素の上にある抽象化だけです。ASuggestionはコンテナとして を持ち、クラスselectを作成するとコンテナとして を持ちます。次に、必要なすべての関数を追加します。重要な部分は、適切なスコープでイベントを呼び出すことであり、これは を介し​​て実行できます。OptionoptionFunction.prototype.bind

このアプローチが気に入った場合は、Google Closure Library をご覧ください。すべてがこのスタイルで構築されています。確かに、これは多くのツールを備えた大規模なライブラリであり、ツールなしでライブラリを使用するのはあまり効率的ではありません。

物事を速く終わらせたいだけなら、jQuery と proxy.

this.container.change($.proxy(this.change, this));

また、ネイティブ JS メソッドを jQuery メソッドに置き換えて、ブラウザー間の互換性を確保します。

于 2013-04-27T08:56:52.057 に答える
1

そのために使用できます$.proxy()

$el.click($.proxy(this.onclick, this));

次に、オブジェクトonclickのコンテキストで呼び出されButtonます。

于 2013-04-27T08:51:38.107 に答える