1

近两天来,我一直在尝试获取 YUI JSON 实用程序:在解析期间添加新对象成员以毫无乐趣地工作。

这对我来说很难,因为我是编码新手。在尝试将不同的 JS 文件、引用和脚本放入项目后,我使用了 Configurator 脚本。

我尝试在 Explorer 和 Firefox 中运行代码;但是,结果表将不会显示。

代码运行是因为页面显示错误消息:“Error Getting Inventory Data”,这是页面代码中的 try/catch 错误消息。

文本编辑器错误控制台中的错误消息是否与未显示的数据有关?

文本编辑器错误控制台显示错误(第 76 行,第 12 列) - 未知属性:错误控制台中的单元格间距


Mozilla Firefox 错误控制台也显示错误:

 Error: ReferenceError: YUI is not defined
    Source File: http://localhost:53753/currency.html 
    Line: 87

Firefox 识别的第 87 行代码行是:

<tr><td colspan="4">Click <em>Get Data</em></td></tr>

YUI 库中的示例代码位于:http: //developer.yahoo.com/yui/examples/json/json_convert_values.html

这是我的完整代码:

<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="utf-8">
        <title>Example: Adding New Object Members During Parsing</title>

    <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=PT+Sans:400,700,400italic,700italic">
    <link rel="stylesheet" href="css/grids-min.css">
    <link rel="stylesheet" href="css/main.css">
    <link rel="stylesheet" href="css/prettify-min.css">
    <link rel="shortcut icon" type="image/png" href="images/favicon.png">

</head>

<body> 
<!--
<a href="https://github.com/yui/yui3"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
-->

    <div id="doc">
        <div id="hd">

        <h1><img src="http://yuilibrary.com/img/yui-logo.png"></h1>

    </div>
        </div>
    <div id="demo">
        <p>Choose a currency, then get the data</p>

        <select>
        <option value="ARS">Argentine Peso</option>
        <option value="AUD">Australian Dollar</option>
        <option value="BRL">Brazilian Real</option>
        <option value="GBP">British Pound</option>
        <option value="CAD">Canadian Dollar</option>
        <option value="CNY">Chinese Yuan</option>
        <option value="COP">Colombian Peso</option>
        <option value="HRK">Croatian Kuna</option>
        <option value="CZK">Czech Koruna</option>
        <option value="DKK">Danish Krone</option>
        <option value="EEK">Estonian Kroon</option>
        <option value="EUR">Euro</option>
        <option value="HKD">Hong Kong Dollar</option>
        <option value="HUF">Hungarian Forint</option>
        <option value="ISK">Iceland Krona</option>
        <option value="INR">Indian Rupee</option>
        <option value="JPY">Japanese Yen</option>
        <option value="KRW">Korean Won</option>
        <option value="LVL">Latvian Lat</option>
        <option value="LTL">Lithuanian Lita</option>
        <option value="MYR">Malaysian Ringgit</option>
        <option value="MXN">Mexican Peso</option>
        <option value="NZD">New Zealand Dollar</option>
        <option value="NOK">Norwegian Krone</option>
        <option value="PHP">Philippine Peso</option>
        <option value="PLN">Polish Zloty</option>
        <option value="RUB">Russian Rouble</option>
        <option value="SGD">Singapore Dollar</option>
        <option value="SKK">Slovak Koruna</option>
        <option value="ZAR">South African Rand</option>
        <option value="LKR">Sri Lanka Rupee</option>
        <option value="SEK">Swedish Krona</option>
        <option value="TRY">Turkey Lira</option>
        <option value="USD" selected="selected">U.S. Dollar</option>
        <option value="CHF">Swiss Franc</option>
        <option value="TWD">Taiwan Dollar</option>
        <option value="THB">Thai Baht</option>
    </select>

        <input type="button" id="demo_go" value="Get Data">

    <table cellspacing="0">
        <caption>Inventory</caption>
            <thead>
        <tr>
            <th>SKU</th>
            <th>Item</th>
            <th>Price (USD)</th>
            <th>Price (<span>USD</span>)</th>
        </tr>
            </thead>
    <tbody>
        <tr><td colspan="4">Click <em>Get Data</em></td></tr>
     </tbody>
   </table>
 </div>

<!-- JS -->
<script type="text/javascript" src="http://yui.yahooapis.com/combo?3.8.1/build/yui-base/yui-base-min.js&3.8.1/build/json-parse/json-parse-min.js&3.8.1/build/json-stringify/json-stringify-min.js"></script>

<script>
    YUI().use("node", "io", "json-parse",function (Y) {

// Safari 4.0.3's native JSON does not support adding members during parse,
// so use JavaScript implementation for consistency
    Y.JSON.useNativeParse = false;

var example = {
    rates : {"USD":1,"EUR":0.6661,"GBP":0.5207,"AUD":1.1225,"BRL":1.609,"NZD":1.4198,"CAD":1.0667,"CHF":1.0792,"CNY":6.8587 ,"DKK":4.9702,"HKD":7.8064,"INR":42.0168,"JPY":109.8901,"KRW":1000,"LKR":107.5269,"MXN":10.1317,"MYR" :3.3167,"NOK":5.3277,"SEK":6.2617,"SGD":1.4073,"THB":33.7838,"TWD":31.1526,"VEF":2.1445,"ZAR":7.6923 ,"BGN":1.3028,"CZK":16.0514,"EEK":10.4275,"HUF":158.7302,"LTL":2.2999,"LVL":0.4692,"PLN":2.1758,"RON" :2.3804,"SKK":20.2429,"ISK":4.8008,"HRK":81.3008,"RUB":24.3309,"TRY":1.1811,"PHP":44.2478,"COP":2000 ,"ARS":3.1289},

    currency : 'USD',

    convert : function (k,v) {
        // 'this' will refer to the object containing the key:value pair,
        // so this step will add a new object member while leaving the original
        // intact (but formatted to two decimal places).  If the original
        // is not needed, just return the converted value.

        if (k === 'Price') {
            var x = Math.round(v * example.rates[example.currency] * 100) / 100;
                this.convertedPrice = x.toFixed(2); // added to item
                    return v.toFixed(2); // assigned to item.Price
        }
        return v;
    },

    updateTable : function (inventory) {
        // Update the column header
        Y.one('#demo table th span').set('innerHTML',example.currency);

        var tbody = Y.one('#demo table tbody'),
            html  = ['<table><tbody>'],
            rowTemplate = '<tr><td>{SKU}</td><td>{Item}</td><td>{Price}</td><td>{convertedPrice}</td></tr>',
            i, len;

        if (inventory) {
            for (i = 0, len = inventory.length; i < len; ++i) {
                html.push(Y.Lang.sub(rowTemplate, inventory[i]));
            }
        } else {
            html.push('<tr><td colspan="4">No Inventory data</td></tr>');
        }

        html.push('</tbody></table>');

        tbody.replace(Y.Node.create(html.join('')).one('tbody'));
    }
};

Y.one('#demo_go').on('click', function (e) {
    // Disable the button temporarily
    this.set('disabled',true);

    // Store the requested currency
    var sel = Y.one("#demo select");
    example.currency = sel.get("options").item(sel.get("selectedIndex")).get("value");

    Y.io('js/json-convert-values-response.json',{
        timeout : 3000,
        on : {
            success : function (xid, res) {
                var inventory;
                try {
                    inventory = Y.JSON.parse(res.responseText,example.convert);

                    example.updateTable(inventory);
                }
                catch(e) {
                    alert("Error getting inventory data");
                }
                finally {
                    Y.one('#demo_go').set('disabled',false);
                }
            },
            failure : function () {
                alert("Error getting inventory data");
            }
        }
    });
});

// Expose example objects for inspection
YUI.example = example;
});
</script>
    </body>
        </html>

更新 - 显然这些 JSON 示例不适用于 jsfiddle,因为它们使用 XHR 来获取 JSON 数据。该数据在他们的服务器上不存在,因此它将归档。所以请忽略小提琴

这是我的问题的 JS Fiddle,有人可以帮我解决这个问题吗?

在解析期间添加新对象成员:http: //jsfiddle.net/DanyB/3ntvw/

谢谢,有好心人看看。

4

2 回答 2

0

昨天早上,我终于设法让这个 JSON 脚本工作了;但是,这是通过解决问题。也就是说,我确信我终于也找到了根本原因——我只是无法纠正它。

下面我记录了我是如何让代码运行的,最后是我研究过的领域的列表。对于那些等不及的人,我只是将我的 JSON 文件名更改为 .JS 并将我的文件路径也更改为 .JS。


我的研究非常广泛,如果记录在案,可能会对面临相同或类似情况的其他人有所帮助。我也详细说明了我的方法;尽管该方法对大多数人来说是常识,但它可能会帮助某人找到问题的根源。

顺便说一句:感谢 YUI 论坛的 Juan 用他的话提供了“第二双眼睛”,它预先确认问题与 JSON 文件未正确加载有关。他也给了我一些他的时间——感激。

通过在 Firefox 中运行该页面,我能够使用错误控制台。这仅在一开始有帮助,因为在我删除了除与示例特别相关的代码之外的任何多余代码之后,即使站点脚本不起作用,Firefox 控制台也没有给出任何错误?

然而,Firefox 错误控制台在早期确实给出了两个明显的错误:一个与服务器未响应调用有关,另一个概述了再次指向服务器 (IIS 7.0) 的 JSON MIME 类型问题。

然后我更改了脚本中的 try/catch 错误消息,使它们都不同。然后我能够根据显示的警报看到应用程序在脚本中的哪个位置失败。

在达到这一点之前,我在谷歌上搜索答案有点偏题——这很容易做到。不过,有条不紊地处理我面前的事情使我能够更直接地专注于具体问题。

我知道我遇到了 JSON 文件无法运行的问题;我还知道服务器没有响应并且服务器没有识别 MIME 类型。因此,如果我在服务器上对 MIME 类型问题进行排序,服务器似乎很可能会识别并运行 JSON 文件。

为了添加一个新的 JSON MIME 类型,我访问了 Microsoft IIS 知识库的以下链接,并阅读了有关如何设置 IIS 7.0 来管理 JSON 文件的说明——确保在我的 IIS 管理器中没有将足够多的 JSON 文件列为已知文件类型.

新 MIME 类型 = JSON 文件扩展名 - .json MIME 类型描述 = application/json

http://technet.microsoft.com/en-us/library/cc725608%28v=ws.10%29.aspx

由于该网站仍然无法正常工作,我看起来更深入。更多研究告诉我,我需要为我的新 JSON MIME 类型配置一个处理程序映射。我再次使用了 Microsoft IIS 站点:(由于信誉点不足,链接被删除)

在某些情况下,您可能需要更改 web.config,所以这是另一个 MS 链接:

(由于信誉点不足,链接被删除)

我又遇到了麻烦,因为 C/Windows/system32/inetsrv/asp.dll 中的 ASP.DLL 丢失了。

为了克服这个问题,我从系统的其他地方找到了另一个副本,并将该文件复制到 inetsrv 文件夹中。该站点仍然无法运行,因此我继续发现系统上应该至少有一个 32 位 asp.dll 文件和一个 64 位 asp.dll 文件。我认为我已将不正确的位 asp.dll 复制到 inetsrv 文件夹中,但我无法确定哪个是哪个;所以,这就是我要去的地方。

然后,当我遇到一个名叫 Colanth 的人在 yahoo 上的回答时,我回到了基础,试图了解更多关于打开 JSON 文件的信息,他说“JSON 是一种技术,而不是一种格式”。

更多地考虑这个陈述,我发现了另一个 JSON 教程,它只专注于在这里创建一个简单的 JSON 调用函数:

(由于信誉点不足,链接被删除)

请注意,本教程还概述了我继续阅读的“JSON 是一种技术”。该教程详细说明了 JSON 是 JavaScript。

然后,我想到如果 JSON 不是格式,而是 JavaScript,我应该将我的 JSON 文件的文件名更改为 .js,然后将我的 JSON 文件路径更改为 .js,因为我的系统可以识别 JavaScript 以查看会发生什么。

所以我做到了,Blam!(引用赏金猎人狗)一切正常!

当然,我需要对 MIME 类型和缺少的 asp.dll 问题进行排序。我认为 asp.dll 可能丢失了,因为我为 VS2012 卸载了 Visual Studio 2010,并且删除 VS2010 可能已经删除了 asp.dll 文件。我知道 VS2012 是基于已安装的 VS2010 版本构建的,因此 VS2012 可能预计 asp.dll 已经安装。说如果是这种情况VS2010不应该删除它;谁知道?

此外,JSON 文件是 JSON 文件是有原因的,所以我需要深入了解该问题。但是,经过大量的努力,我现在有一个工作要做。

以下是我检查的其他一些内容,它们也可能会给您一些想法:

URL'S,文件路径和文件名

本地主机——站点和响应文件在哪个端口上运行

使用验证器获取想法的 JSON 脚本:http: //jsonlint.com/

检查他的代码是否有错误和拼写错误

尝试在 2.0 和 4.0 模式下运行 IIS

检查 JSON 的 web.config 脚本

尝试在 html、aspx、cshtml 和 php 网站中运行代码

尝试将 JSON 文件移动到不同的位置;检查 JSON 文件路径

使用配置器尝试了本地和外部的不同 YUI 配置

查看了不同的浏览器安全设置

更改 Firefox about:config: 为 security.fileuri.strict_origin_policy

增加代码中的超时设置

检查你的系统处理 JSON MIME 类型

IIS 的版本是否正确 5.0、6.0、7.0、7.5 等

检查服务器 WCF 设置

更改代码

更改全局设置

于 2013-03-12T00:05:05.273 回答
0

As Bergi says in the comments above, it looks like the script did not load or execute early enough.

ONE POSSIBLE SOLUTION...

To make sure it is, you should declare the YUI script tag in the head of your HTML. Try that first to see if it solves your problem. However...

...

WAITING UNTIL READY

You should put your other code in the head too, but specify it so that it only loads when the whole document has loaded.

The simplest way to do this would be:

window.onload = function () { // what to do when window has loaded
    YUI().use("node", "io", "json-parse",function (Y) {

    // ... the code in your callback function, as provided above ...

    }); // end callback -- UPDATED
}; // end window onload function

YUI has its own way of handling code that should when the document is ready...

YAHOO.util.Event.onDOMReady

But as your problem is with YUI not being defined, I'm not sure this will help.

...

CHECKS AND SAFEGUARDS PATTERN?

A more sophisticated pattern could involve setting an intermittent check to see if YUI is defined and then cancelling the check once it is and executing the code you need. That would use a method called setInterval() and look something like this:

var checkYUI = setInterval(function() { // create a function to be executed within the interval and assign the interval to a global variable
    if (YUI) { // check the global variable `YUI` exists
        clearInterval(checkYUI); // cancel the interval check
        YUI().use("node", "io", "json-parse",function (Y) { // now we know `YUI` exists call its `use()` method
            // ... the code in your callback function, as provided above ...
        }
    }
}, 100); // checks every 100 ms

You could make the checking more complicated still by, for example, checking that YUI is an object, that it has a use() method, etc. But hopefully this will suffice to show how it could work.

I'm not sure what you did in your previous trials that made them succeed whilst this one failed but it might be worth studying them to see if such checks/safeguards are already in place.

于 2013-03-04T15:43:37.843 回答