1

私はwidgetオブジェクト指向のJavaScriptでJavaScriptを書き込もうとしています。少なくとも、JSのクラスとほぼ同等であると私が理解しているものです。

私が達成しようとしているのは、状態を変更するメニューだけです。疑似で;

  • ウィジェットのロード時に、年グループを含むメニューを入力#navします。<ul> <li>
  • 年グループをクリックしたら、そのグループ<li>を空にして、その年のチューターグループを再入力し、リンクを追加します。#nav ul<li> <li>return
  • リンクをクリックしたら、上記のすべての機能を利用できるようにしながら、元の年のグループメニューをreturn#navにして再入力します。 <ul>

歴史的に、つまりこれまで、私は「埋め込み」関数を使用して、すべてを同じDOMレイヤー/タイミング内に維持しようとしてきました。これがどのように機能するのか、またはこれが適切なことであるのかどうかはよくわかりませんが、コード自体は機能しているようです。

これは私が以前にそれを行った方法の例です:

var GroupsDisplayHTML = '<h2>Tutor Groups</h2>' +
    '<ul><li><a class="year" href="javascript:void(0);" title="Year 9" id="9">Year 9</a></li>' +
    '<li><a class="year" href="javascript:void(0);" title="Year 10" id="10">Year 10</a></li>' +
    '<li><a class="year" href="javascript:void(0);" title="Year 11" id="11">Year 11</a></li>' +
    '<li><a class="year" href="javascript:void(0);" title="Year 12" id="12">Year 12</a></li>' +
    '<li><a class="year" href="javascript:void(0);" title="Year 13" id="13">Year 13</a></li></ul>';

$("div#groups").html(GroupsDisplayHTML);

$('a.year').click( function() {
    var Groups;
    var Groups_Sorted = [];

    Frog.API.get('groups.getAll',
    {
        'onSuccess': function (data) { Groups = data; },
        'onError': function(err) { alert(err); }
    });

    for (var i = 0; i < Groups.length; i++) {
        var Year = $(this).attr("id");

        if (Groups[i].name.indexOf(Year) == 0 && Groups[i].name.indexOf('/Tp') != -1) {
            var arrayToPush = { 'id': Groups[i].id, 'name': Groups[i].name };
            Groups_Sorted.push(arrayToPush);
        }
    }

    GroupsDisplayHTML = '<h2>Year ' + Year + '</h2><ul>';

    for(var i = 0; i < Groups_Sorted.length; i++){
        GroupsDisplayHTML += '<li><a class="group" href="javascript:void(0);" title="' + Groups_Sorted[i].id + '" id="' + Groups_Sorted[i].id + '">' + 
            Groups_Sorted[i].name + ' <span style="font-size:10px;color:#bbb;">(' + Groups_Sorted[i].name + ')</span></a></li>';
    }

    GroupsDisplayHTML += '<li><a class="return" href="javascript:void(0);">&lt;- Back to Year Groups</a></li></ul>';

    $("div#groups").html(GroupsDisplayHTML);

    $('a.group').click( function() {
        var Group_ID = $(this).attr("id");
        AssignPoints.getUsers(Group_ID);
    });

    $('a.return').click( function() {
        AssignPoints.displayGroups(data);
    });
});

しかし、今、私はそれを行うためのより良い方法がjQueryのon関数を使用することであるかどうか疑問に思っています。これが私が現在書いているコードです(*状態の変化メニューを実現するためだけに):

var TutorGroupPoints = {
    URL: 'http://staff.curriculum.local/frog/rewards.php',
    currentUser: UWA.Environment.user.id,
    groupsObject: { },
    sortedArray: [ ],
    navHTML: '<h2>Tutor Groups</h2>' +
        '<ul>' +
            '<li><a class="year" title="Year 9" id="9">Year 9</a></li>' +
            '<li><a class="year" title="Year 10" id="10">Year 10</a></li>' +
            '<li><a class="year" title="Year 11" id="11">Year 11</a></li>' +
            '<li><a class="year" title="Year 12" id="12">Year 12</a></li>' +
            '<li><a class="year" title="Year 13" id="13">Year 13</a></li>' +
        '</ul>',

    init: function() {
        /* caching outer this -> AJAX scope problems */
        var that = this;

        /* retrieve all of the user groups from Frog VLE and store them in an object-level variable */
        Frog.API.get('groups.getAll',
        {
            'onSuccess': function (data) { that.groupsObject = data; },
            'onError': function(err) { alert(err); }
        });

        /* populate the div#nav with our year group UL */
        $('#nav').append(this.navHTML);

        /* using "on" because the LIs have been created in the DOM? */
        $('#nav ul').on("click", "li a", function(e) {
            e.preventDefault();
            that.yearClick( $(this).attr("id") );
        });
    },

    yearClick: function(year) {
        /* run through groupsObject and pull out any tutor groups found in the year we've clicked on
           then put those into our sortedArray */
        for (var i = 0; i < this.groupsObject.length; i++) {
            if (this.groupsObject[i].name.indexOf(year) == 0 && this.groupsObject[i].name.indexOf('/Tp') != -1) {
                /* all we need is name and id */
                var arrayToPush = { 'id': this.groupsObject[i].id, 'name': this.groupsObject[i].name };
                this.sortedArray.push(arrayToPush);
            }
        }

        /* clear the existing UL from div#nav */
        $('#nav ul').empty();

        /* populate div#nav's UL with LIs of our tutor groups (label being name, attr="id" being id) and
           clickable links for each */
        for (var i = 0; i < this.sortedArray.length; i++) {
            $('#nav ul').append('<li><a class="tutor" id="' + this.sortedArray[i].id + '">' + this.sortedArray[i].name + '</a></li>');
        }

        /* add a "return" link to view other years' tutor groups */
        $('#nav ul').append('<li><a id="return">&lt;- Return</a></li>');

        /* upon clicking the return link, empty #nav ul then re-append our navHTML from earlier */
        $('#nav ul').on("click", "a#return", function(e) {
            e.preventDefault();
            $('#nav ul').empty();
            $('#nav').append(this.navHTML);
        });

        /* upon clicking any of our tutor group LIs, display that link's id so that we can use it in
           another function to actually display some content */
        $('#nav ul').on("click", "a.tutor", function(e) {
            e.preventDefault();
            alert( $(this).attr("id") );
        });
    }

};

widget.onLoad = function(){
    /* run our "class" */
    TutorGroupPoints.init();
}

そしてHTML:

<div id="wrapper">
    <div id="nav">

    </div>
    <div id="content">

    </div>
</div>

ここでjsFiddleを作成しました。これは、コードを少し操作したものです(つまり、アクセスできないFrog API呼び出しを削除し、固定オブジェクトに置き換えました)。うまくいけば、これは適切に機能します。

ここでの問題は、戻るボタンをクリックしても何も起こらないことです。さらに、戻るボタンを修正すると、クリックしても何も起こらないリンクがいくつか提供されるのではないかと思います。

理想的には、コードの下端にあるように、ユーザーが特定の家庭教師グループをクリックしたときに、TutorGroupPointsクラス内で別の関数を実行したいと思います。これは私の戻るボタンなどにどのように影響しますか?その後、「現在の」機能から実行されていないため、動作を停止しますか?

私のコードの問題に対する「単なる」答え以上に、私はいくつかの方向性を望んでいます。つまり、私が書いた最近のコードは古いものよりも優れていますか?on埋め込まれたjQuery関数と通信クラス関数を使用する必要がありますか、それとも使用する必要がありますか?

前もって感謝します、

4

1 に答える 1

1

簡単な答え: http: //jsfiddle.net/byzgv/4/

OOPの側面についてはよくわかりませんが、これはあなたのシナリオのようです。

  1. ページが読み込まれると、リストがdivに挿入されます。
  2. このリストにいくつかのイベントハンドラーを追加します
  3. リストアイテムをクリックすると、イベントハンドラーが実行され、リストアイテムが変更されます。
  4. 「戻る」リスト項目をクリックすると、「何もしません」。

あなたのフィドルでは、「戻る」リスト項目をクリックすると何かが行われ、このリストが空になります。これは部分的にあなたがそれをするように頼んだことです:

$('#nav').on("click", "ul a#return", function(e) {
    e.preventDefault();
    $('#nav ul').empty();
    $('#nav').append(this.navHTML);
});

したがって、このイベントハンドラーが起動し、最初の2つの命令が機能しました。append別のコンテキストにいるため、への呼び出しは機能しませんthis-TutorGroupPointsオブジェクトを参照していません。したがって、オブジェクトを明示的に参照することでこれを修正できます。

$('#nav').on("click", "ul a#return", function(e) {
    e.preventDefault();
    $('#nav ul').empty();
    $('#nav').append(TutorGroupPoints.navHTML);
});

$('#nav').empty();(ちなみに、まったく新しいリストを追加しているので、代わりに追加する必要があります$('#nav ul').empty();

次に、ご想像のとおり、[戻る]アイテムをクリックすると、クリックイベントに応答しない新しいリストが表示されます。onこれは、関数の呼び出し方法が原因です。呼び出すjQueryオブジェクトonは、イベントハンドラーのセットアップ時に存在している必要があります。関数では、を呼び出す前にinitリストを追加するため、イベントハンドラーを設定するときにリストが存在します。しかし後で、このリストをゴミ箱に捨てて置き換えます。divon

イベントハンドラーを最初のリストだけでなくすべてのリストで機能させるには、イベントハンドラーを最初から存在し、変更されない要素、つまり#navdivにアタッチする必要があります。それで

$('#nav ul').on("click", "li a", function(e) {

になることができる

$('#nav').on("click", "ul li a", function(e) {
于 2012-08-15T10:27:01.177 に答える