子 JSON 对象未定义时未定义

Posted

技术标签:

【中文标题】子 JSON 对象未定义时未定义【英文标题】:Child JSON object undefined when its not 【发布时间】:2012-03-16 03:56:19 【问题描述】:

我在页面源中有一个 JSON 对象数组,除了子对象(类别)之外,它们都可以工作。

这是cshtml中的代码:

      <script type="text/javascript">
var initialData = @Html.Raw(Json.Encode(ViewBag.OfferItems));
</script>

这是生成的页面源代码:

       <script type="text/javascript">
var initialData = ["Id":1,"Name":"Item1","ProductVariantLinks":["category":"Id":2,"Name":"Basic Pizza","Products":null,"product":"Id":1,"Name":"Margherita","Description":null,"ProductVariants":null,"productVariant":"Id":1,"Name":"10 inch","category":"Id":2,"Name":"Basic Pizza","Products":null,"product":"Id":2,"Name":"Zeno","Description":null,"ProductVariants":null,"productVariant":"Id":4,"Name":"8 inch"],"Id":2,"Name":"Item2","ProductVariantLinks":[]];
</script>

据我所知,类别存在并包含属性,但它在 IE 的调试器中显示为未定义。

我有什么遗漏吗?

附: JSON 是有效的。

更新

我正在使用 knockoutjs,并且类别在 inialdata 中,直到它执行 ko.applybindings。我不确定它为什么会这样做,代码如下:

/// <reference path="jquery-1.5.1.js" />
/// <reference path="knockout-2.0.0.js" />
var ProductVariantLink = function() 
    var self = this;
    self.category = ko.observable();
    self.product = ko.observable();
    self.productVariant = ko.observable();

    // Whenever the category changes, reset the product selection
    self.category.subscribe(function() 
        self.product(undefined);
        self.productVariant(undefined);
    );
;

var OfferItem = function() 
    var self = this;
    self.Name = new String();
    self.ProductVariants = new Array();
;

var SpecialOfferItemModel = function (specialOfferItems) 
    var self = this;
    self.specialOfferItems = ko.observableArray(ko.utils.arrayMap(specialOfferItems, function (specialOfferItem) 
        return  Id: specialOfferItem.Id, Name: specialOfferItem.Name, ProductVariants: ko.observableArray(specialOfferItem.ProductVariantLinks) ;
    ));

    self.addSpecialOfferItem = function () 
        self.specialOfferItems.push(
            Id: "",
            Name: "",
            ProductVariants: ko.observableArray()
        );
    ;

    self.removeSpecialOfferItem = function (specialOfferItem) 
        self.specialOfferItems.remove(specialOfferItem);
    ;

    self.addProductVariant = function (specialOfferItem) 
        specialOfferItem.ProductVariants.push(new ProductVariantLink());
    ;

    self.removeProductVariant = function (ProductVariant) 
        $.each(self.specialOfferItems(), function ()  this.ProductVariants.remove(ProductVariant) )
    ;

    self.save = function () 
        var OfferItems = new Array();
        $.each(self.specialOfferItems(),
                function () 
                    var item = this;
                    var offer = new OfferItem();
                    offer.Name = item.Name;
                    $.each(item.ProductVariants(),
                    function () 
                        offer.ProductVariants.push(this.ProductVariant);
                    );
                    OfferItems.push(offer);
                );
                self.lastSavedJson(JSON.stringify(ko.toJS(self.specialOfferItems()), null, 2));
        return false;
    ;

    self.lastSavedJson = ko.observable("");
;
var model = new SpecialOfferItemModel(initialData);
ko.applyBindings(model);
$(function () 
    $('#myForm').submit(function () 
        model.save();
    );
);



<table class="specialOfferItemsEditor">
        <tr>
            <th>
            </th>
            <th>
                Name
            </th>
            <th>
                ProductVariants
            </th>
        </tr>
        <tbody data-bind="foreach: specialOfferItems">
            <tr>
                <td>
                    <div>
                        <a href="#" data-bind="click: $root.removeSpecialOfferItem">Delete</a></div>
                </td>
                <td>
                    <input data-bind="value: Name" />
                </td>
                <td>
                    <table>
                        <tr>
                            <th>
                                Category
                            </th>
                            <th>
                                Product
                            </th>
                            <th>
                                ProductVariant
                            </th>
                        </tr>
                        <tbody data-bind="foreach: ProductVariants">
                            <tr>
                                <td>
                                    <select data-bind='options: ProductCategories, optionsText: "Name", optionsCaption: "Select...", value: category, uniqueName: true'>
                                    </select>
                                </td>
                                <td data-bind="with: category">
                                    <select data-bind='options: Products, optionsText: "Name", optionsCaption: "Select...", value: $parent.product, uniqueName: true' >
                                    </select>
                                </td>
                                <td data-bind="with: product">
                                    <select data-bind='options: ProductVariants, optionsText: "Name", optionsCaption: "Select...", value: $parent.ProductVariant, uniqueName: true'
                                        >
                                    </select>
                                </td>
                                <td>
                                    <a href='#' data-bind='click: $root.removeProductVariant'>Delete</a>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    <a href='#' data-bind='click: $root.addProductVariant'>Add Product Variant</a>
                </td>
            </tr>
        </tbody>
    </table>

【问题讨论】:

您是否尝试过硬编码 var initialData 您提供的 JSON 字符串,而不是从 ViewBag.OfferItems 中提取它? 实际生成的页面源是什么样的?您粘贴的不能来自您粘贴的源代码,因为它末尾缺少分号... 它确实有一个分号,当我编辑我的帖子时它确实丢失了。 【参考方案1】:

JSON 没有像您预期的那样进入。我分配了您在上面提供的 JSON 字符串,我的 IE 调试器能够毫无问题地找到“类别”。

截图:https://i.stack.imgur.com/cI60U.jpg

尝试console.log(或alertJSON.stringify(initialData);

【讨论】:

谢谢你,我还没有意识到 knockoutjs 中的 ko.applyBindings 是导致类别变得未定义的行。

以上是关于子 JSON 对象未定义时未定义的主要内容,如果未能解决你的问题,请参考以下文章

CoreData:第一次加载 NSManagedObject 时未访问自定义属性访问器

反序列化 Web.API 参数时未调用自定义 Json.NET JsonConverter

从 mongoose 数据库获取值时未定义

类型错误:在 reactjs 中使用 fetch 读取 json 时未定义项目

Laravel - 在部署自定义 Artisan 命令时未部署 composer.json 文件

尝试使用 useContext() 获取对象时未定义对象