3

jQueryJSON呼び出しと組み合わせたJavascript変数スコープに少し苦労しています。残念ながら、このスクリプトはデータが必要なため、jsFiddleに投稿できません。

データを動的にロードして、ユーザーの画面に出力しようとしています。これで、データを初めてロードするメソッドのみを作成しました。後で、テーブル行のデータを更新する更新メソッドを作成したいと思います。

しかし今、私は可変スコープに問題があります。$ .pcw.outstandingInvoices.init()が呼び出されると、次のエラーが発生します。

ypeError: can't convert undefined to object
this.outstandingInvoicesArray[key] = entry;

私のコード:

-- Post is getting to long, so removed the first code i've used. -- 

誰かが私が間違っていることを教えてもらえますか?

前もって感謝します!

---更新---皆さんが私に言ったことを編集しましたが、それでもエラーが発生します...誰かが私が間違っていることを教えてもらえますか?

私の新しいコードとエラー:

-- Post is getting to long, so removed the first update of the code. -- 

エラー:

Initializing outstandingInvoices class.
Loading outstanding invoices from server.

TypeError: context.outstandingInvoicesObject is undefined
if (context.outstandingInvoicesObject.length == 0) {

TypeError: can't convert undefined to object
self.outstandingInvoicesObject[key] = entry;

--UPDATE 2-コードを編集したばかりで、エラーは発生していませんが、outstandingInvoicesObjectのデータが適切に保存されていないため、メソッドaddOutstandingInvoicesTableは請求書を見つけることができません。私はコンソールを分析してきましたが、メソッドの実行順序に何らかの問題があるようです...

コード:

$.pcw.outstandingInvoices = function () {
    var context = this;
    context.outstandingInvoicesObject = [];

    context.init = function ()
    {
        console.log('Initializing outstandingInvoices class.');

        context.loadData();        
        context.removeLoader();
        context.addOutstandingInvoicesToTable();
    };

    context.loadData = function ()
    {
        console.log('Loading outstanding invoices from server.');

        jQuery.getJSON('/ajax/outgoing-invoices/find-outstanding.json', function (data)
        {   
            var i = 0;
            jQuery.each(data, function (key, entry)
            {
                context.outstandingInvoicesObject[key] = entry;

                ++i;
            });

            console.log('Loaded ' + i + ' invoices');
        }).error(function () {
            console.error('Error while loading outstanding invoices.');
        });
    };

    context.removeLoader = function ()
    {
        console.log('Removing loader');

        jQuery('table#invoices-outstanding tr.ajax-loader').fadeOut();
    };

    context.addOutstandingInvoicesToTable = function()
    {
        console.log('Outputing invoices to table');

        if (context.outstandingInvoicesObject.length == 0) {
            console.log('No outstanding invoices found');
        }

        jQuery.each(context.outstandingInvoicesObject, function (key, entry)
        {
            // This is a new outstanding invoice
            var rowClass = 'info';

            switch(entry.status)
            {
                case 'Created':
                case 'Sent':
                case 'Paid': // The invoices with Paid statuses aren't show here, because we only show the oustanding invoices on this page.
                    rowClass = 'success';
                break;

                case 'First reminder':
                case 'Second reminder':
                case 'Partially paid':
                    rowClass = 'warning';
                break;

                case 'Third reminder':
                case 'Collection agency':
                case 'Judicial proceedings':
                    rowClass = 'error';
                break;
            }

            jQuery('table#invoices-outstanding tbody').append(
                outstandingInvoice = jQuery('<tr/>', {
                    id: 'outgoing-invoice-' + key,
                    class: rowClass
                }).append(
                    jQuery('<td/>', {
                        class: 'id',
                        text: key
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'debtor-name',
                        text: entry.debtor_name
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'amount',
                        text: entry.amount
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'date',
                        text: entry.created_timestamp
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'status',
                        text: entry.status
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'creator',
                        text: entry.creator
                    })
                )            
            );
        });
    }
}


// When document is ready
(function()
{
    var invoices = new $.pcw.outstandingInvoices();
    invoices.init();
})();

コンソール出力:

Initializing outstandingInvoices class.

Loading outstanding invoices from server.
GET /ajax/outgoing-invoices/find-outstanding.json
200 OK
509ms   

Removing loader

Outputing invoices to table

No outstanding invoices found

Loaded 29 invoices

ありがとう

4

5 に答える 5

1

thisオブジェクトのバックアップを作成して、オブジェクトを参照しない関数で使用できるようにします。

loadData: function ()
{
    console.log('Loading outstanding invoices from server.');
    var self = this;
    jQuery.getJSON('/ajax/outgoing-invoices/find-outstanding.json', function (data)
    {            
        jQuery.each(data, function (key, entry)
        {
            self.outstandingInvoicesArray[key] = entry;
        });
    }).error(function () {
        console.error('Error while loading outstanding invoices.');
    });
},
于 2013-01-31T20:42:32.597 に答える
1

配列として作成outstandingInvoicesArrayしていますが、オブジェクトとしてアクセスしようとしています。

outstandingInvoicesArray: []
[...]
this.outstandingInvoicesArray[key] = entry;

代わりにオブジェクトとして作成します。

outstandingInvoicesArray: {}
于 2013-01-31T20:44:27.977 に答える
1

これを使用する場合は、オブジェクトを初期化するときにnewキーワードを使用する必要があります。

$.pcw.outstandingInvoices = function(){
   var context = this;//replace every instance of "this" in your class with the context var

   context.init= function ()
    {
        console.log('Initializing outstandingInvoices class.');

        context.loadData();

    }
    //the rest of functions defined below
}
var invoices = new $.pcw.outstandingInvoices();
invoices.init();

編集:残りのエラーを修正するには、selfの代わりにcontextを使用してみて、コンテキストでoutstandingInvoicesObjectを宣言します。

$.pcw.outstandingInvoices = function () {
    var context = this;
    context.outstandingInvoicesObject = [];

    context.init = function ()
    {
        console.log('Initializing outstandingInvoices class.');

        context.loadData();

    };

    context.loadData = function ()
    {
        console.log('Loading outstanding invoices from server.');



        jQuery.getJSON('/ajax/outgoing-invoices/find-outstanding.json', function (data)
        {            
            jQuery.each(data, function (key, entry)
            {
                context.outstandingInvoicesObject[key] = entry;
            });
            //now that we have data, call add the invoices to the table
            context.removeLoader();
            context.addOutstandingInvoicesToTable();
        }).error(function () {
            console.error('Error while loading outstanding invoices.');
        });
    };

    context.removeLoader = function ()
    {
        jQuery('table#invoices-outstanding tr.ajax-loader').fadeOut();
    };

    context.addOutstandingInvoicesToTable = function()
    {
        if (context.outstandingInvoicesObject.length == 0) {
            console.log('No outstanding invoices found');
        }

        jQuery.each(context.outstandingInvoicesObject, function (key, entry)
        {
            // This is a new outstanding invoice
            var rowClass = 'info';

            switch(entry.status)
            {
                case 'Created':
                case 'Sent':
                case 'Paid': // The invoices with Paid statuses aren't show here, because we only show the oustanding invoices on this page.
                    rowClass = 'success';
                break;

                case 'First reminder':
                case 'Second reminder':
                case 'Partially paid':
                    rowClass = 'warning';
                break;

                case 'Third reminder':
                case 'Collection agency':
                case 'Judicial proceedings':
                    rowClass = 'error';
                break;
            }

            jQuery('table#invoices-outstanding tbody').append(
                outstandingInvoice = jQuery('<tr/>', {
                    id: 'outgoing-invoice-' + key,
                    class: rowClass
                }).append(
                    jQuery('<td/>', {
                        class: 'id',
                        text: key
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'debtor-name',
                        text: entry.debtor_name
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'amount',
                        text: entry.amount
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'date',
                        text: entry.created_timestamp
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'status',
                        text: entry.status
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'creator',
                        text: entry.creator
                    })
                )            
            );
        });
    }
}
于 2013-01-31T20:44:49.393 に答える
1

以下はあなたの問題を解決するはずです。意図したとおりにoustandingInvoicesObjectを宣言していませんでした。あなたの場合、それは「this」または「context」から外れていなければなりませんでした。

また、oustandingInvoicesObjectをオブジェクトではなく配列として宣言しました。オブジェクトのように配列にプロパティを追加することはできません。

どうなるか教えてください。

$.pcw.outstandingInvoices = function () {
    var context = this;
    context.outstandingInvoicesObject = {};

    context.init = function ()
    {
        console.log('Initializing outstandingInvoices class.');

        context.loadData();
        context.removeLoader();
        context.addOutstandingInvoicesToTable();
    };

    context.loadData = function ()
    {
        console.log('Loading outstanding invoices from server.');

        var self = this;

        jQuery.getJSON('/ajax/outgoing-invoices/find-outstanding.json', function (data)
        {            
            jQuery.each(data, function (key, entry)
            {
                self.outstandingInvoicesObject[key] = entry;
            });
        }).error(function () {
            console.error('Error while loading outstanding invoices.');
        });
    };

    context.removeLoader = function ()
    {
        jQuery('table#invoices-outstanding tr.ajax-loader').fadeOut();
    };

    context.addOutstandingInvoicesToTable = function()
    {
        if (context.outstandingInvoicesObject.length == 0) {
            console.log('No outstanding invoices found');
        }

        jQuery.each(context.outstandingInvoicesObject, function (key, entry)
        {
            // This is a new outstanding invoice
            var rowClass = 'info';

            switch(entry.status)
            {
                case 'Created':
                case 'Sent':
                case 'Paid': // The invoices with Paid statuses aren't show here, because we only show the oustanding invoices on this page.
                    rowClass = 'success';
                break;

                case 'First reminder':
                case 'Second reminder':
                case 'Partially paid':
                    rowClass = 'warning';
                break;

                case 'Third reminder':
                case 'Collection agency':
                case 'Judicial proceedings':
                    rowClass = 'error';
                break;
            }

            jQuery('table#invoices-outstanding tbody').append(
                outstandingInvoice = jQuery('<tr/>', {
                    id: 'outgoing-invoice-' + key,
                    class: rowClass
                }).append(
                    jQuery('<td/>', {
                        class: 'id',
                        text: key
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'debtor-name',
                        text: entry.debtor_name
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'amount',
                        text: entry.amount
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'date',
                        text: entry.created_timestamp
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'status',
                        text: entry.status
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'creator',
                        text: entry.creator
                    })
                )            
            );
        });
    };
};

// When document is ready
(function(){
    var invoices = new $.pcw.outstandingInvoices();
    invoices.init();
})();
于 2013-02-01T19:42:02.623 に答える
0

問題はこれで解決されました。皆さんが言ったことと、AJAX呼び出しが非同期であるという問題の組み合わせでした。

最終的な動作コードは次のとおりです。

$.pcw.outstandingInvoices = function () {
    var context = this;
    context.outstandingInvoicesObject = new Object();

    context.init = function ()
    {
        console.log('Initializing outstandingInvoices class.');

        context.loadData();                
        context.removeLoader();
        context.addOutstandingInvoicesToTable();
    };

    context.loadData = function ()
    {
        console.log('Loading outstanding invoices from server.');

        $.ajax({
            url: '/ajax/outgoing-invoices/find-outstanding.json',
            dataType: 'json',
            async: false,
            success: function(data) {                
                var i = 0;            
                jQuery.each(data, function (invoiceId, invoiceDetails)
                {
                    context.outstandingInvoicesObject[invoiceId] = invoiceDetails;

                    ++i;                                
                });

                console.log('Loaded ' + i + ' invoices');       
            }
        }).error(function () {
            console.error('Error while loading outstanding invoices.');
        });
    };

    context.removeLoader = function ()
    {
        console.log('Removing loader');

        jQuery('table#invoices-outstanding tr.ajax-loader').fadeOut();
    };

    context.addOutstandingInvoicesToTable = function()
    {
        console.log('Outputing invoices to table');           

        if (context.outstandingInvoicesObject.length == 0) {
            console.log('No outstanding invoices found');            
        }

        jQuery.each(context.outstandingInvoicesObject, function (key, entry)
        {
            // This is a new outstanding invoice
            var rowClass = 'info';

            switch(entry.status)
            {
                case 'Created':
                case 'Sent':
                case 'Paid': // The invoices with Paid statuses aren't show here, because we only show the oustanding invoices on this page.
                    rowClass = 'success';
                break;

                case 'First reminder':
                case 'Second reminder':
                case 'Partially paid':
                    rowClass = 'warning';
                break;

                case 'Third reminder':
                case 'Collection agency':
                case 'Judicial proceedings':
                    rowClass = 'error';
                break;
            }

            jQuery('table#invoices-outstanding tbody').append(
                outstandingInvoice = jQuery('<tr/>', {
                    id: 'outgoing-invoice-' + key,
                    class: rowClass
                }).append(
                    jQuery('<td/>', {
                        class: 'id',
                        text: key
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'debtor-name',
                        text: entry.debtor_name
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'amount',
                        text: entry.amount
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'date',
                        text: entry.created_timestamp
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'status',
                        text: entry.status
                    })
                ).append(
                    jQuery('<td/>', {
                        class: 'creator',
                        text: entry.creator
                    })
                )            
            );
        });
    }
}

// When document is ready
(function()
{   
    var invoices = new $.pcw.outstandingInvoices();
    invoices.init();
})();

助けてくれてありがとう、みんな!

于 2013-02-02T11:23:43.453 に答える