JSON节点返回'未定义'从ajax请求插入后

JSON node returns 'undefined' after insert from ajax request

本文关键字:请求 插入 ajax 节点 JSON 未定义 返回      更新时间:2023-09-26

我有一个jQuery插件,它通过ajax调用加载json数据——返回的数据插入到现有对象中。

当我尝试引用新插入的节点时,我会得到一个"未定义"——尽管数据在控制台中看起来不错。

如果我手动定义数据,那么我可以很好地访问它——即使结构是相同的。

数据加载在init事件上(.then()中会有多个函数调用,但我只是显示失败的初始调用-每个调用都将引用相同的_t.creditions.base.x,其中x是插入的json):

 var _t = this;
_t.init = function() {
        _s = $.extend({}, defaults, options);
        $.when( 
            loadDefaultCriteria() 
        ).then(
            renderCommunities
        );
    }

这会加载数据:

_t.criteria = {
        base: {},
        current: {},
        picks:{}
    }; 
var loadDefaultCriteria = function() {
        $.getJSON
        (
            '/path/to/script.php',
            {
                action: 'loadDefaultCriteria',
            })
            .done( function( data ){
                _t.criteria.base = data;
            })
            .fail( function( jqxhr, textStatus, error ) {
                var err = textStatus + ", " + error;
                console.log( "Request Failed: " + err );
            });
        }

这是失败的代码(调试日志仍然存在)

var renderCommunities = function(){
        console.log(_t.criteria);
        var c = $(_s.containers.communities);
        var i = _t.criteria.base.communities;
        console.log(i);
        c.empty();
        c.append('<ul>');
        $.each( i, function( idx, _i ) {
                console.log(_i);
            });
    }

console.log(_t.scriteria)输出如下(我只显示基本对象的扩展树):

Object {base: Object, current: Object, picks: Object}
    base: Object
        communities: Object
             subscribed: Array[2]
                0: Object
                1: Object
             unsubscribed: Array[1]
                0: Object
   current: Object
   picks: Object

无论我尝试在base下面引用哪个对象,它们都会返回"undefined",所以在console.log(_t.base.communities)上面的代码中,它们都将返回undefined。

如何将JSON数据/节点的子集插入到现有对象中,然后访问它们?

$.when需要一个Deferred对象作为其参数。现在,loadDefaultCriteria没有返回任何内容,所以$.whenundefined作为其参数。相反,loadDefaultCriteria必须return$.getJSON(...)调用创建的Deferred对象:

var loadDefaultCriteria = function() {
    return $.getJSON( ... );
}

您的renderCommunities呼叫发生在getJSON呼叫完成之前。console.log调用显示更新对象的原因是,您在$.getJSON调用强制执行后检查了记录的对象,而console.log始终显示检查时存在的对象。事件顺序为:

  1. loadDefaultCriteria中发起getJSON调用
  2. 在对象更新之前立即运行renderCommunities
  3. 在控制台输出中显示未展开的对象
  4. $.getJSON解析并更新对象
  5. 几秒钟后,展开控制台输出中的对象,查看当前存在的对象