与Durandal的第一个javascript项目。试图从第三方API获取数据

时间:2015-03-16 21:56:37

标签: javascript api durandal

所以我正在开展一个项目,游戏玩家可以将他们的表现与同等技能水平的同龄人进行比较。我可以得到一个代码的原型在durandal结构之外工作,但是当我尝试跟随其他示例同时提供我自己的数据源时,我只是无法将它们全部组合在一起。

这是我的代码:

define(function (require) {
var http = require('plugins/http'),
    ko = require('knockout');
var url = 'https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/',
    key = '?api_key=#################################';

return {
    name: ko.observable,
    getSummoner: function() {
        var that = this;
        if (this.name.length > 0) {
            return;
        }
        return http.jsonp(url + name + key, 'jsoncallback').then(function(response){
            that.name(response.items);
        });
    }
};
}); 

将#替换为主机建议我不共享的个人API密钥。如有必要,我会提供一个,稍后再更改。

我在这里有两个具体问题:

  1. 我从教程中获得了函数结构。我不知道为什么我需要用IF语句检查长度。究竟是什么回归?

  2. 此api调用返回一个内部嵌套对象的JSON对象。我想要的是在视图中显示嵌套对象中的键和值作为li。现在我甚至不能告诉我它是否真的抓住了对象。

  3. 这是我的HTML:

    <section>
      <h2>Hello! What user would you like to investigate?</h2>
      <form class="form-inline">
        <fieldset>
           <label>Name</label>
           <input type="text" data-bind="value: name, valueUpdate: 'afterkeydown'"/> <!--Text input box-->
           <button type="submit" class="btn" data-bind="click: getSummoner, enable: name">Click Me</button><!--This button has both a class and an ID, 
           Css is linked from index.html-->
           <ul data-bind="foreach: name">
                <li data-bind="text:$data"></li>
            </ul>
        </fieldset>
      </form>
    </section>
    

    我期望看到的只是一个项目,它表示对象或任何名称被输入到输入框中。我得到的是什么。

    返回的对象(附带我的用户名)如下所示:

    {"ryebrush":{"id":25500750,"name":"RyeBrush","profileIconId":551,"summonerLevel":30,"revisionDate":1426533699000}}
    

    我希望能够访问ryebrush.id,ryebrush.profileIconId,依此类推。帮助

    编辑:此外,它预装在输入框中:

    function (b){function c(){if(0<arguments.length)return c.Ka(d,arguments[0])&&(c.P(),d=arguments[0],c.O()),this;a.k.zb(c);return d}var d=b;a.N.call(c);a.a.sa(c,a.m.fn);c.o=function(){return d};c.O=function(){c.notifySubscribers(d)};c.P=function(){c.notifySubscribers(d,"beforeChange")};a.s(c,"peek",c.o);a.s(c,"valueHasMutated",c.O);a.s(c,"valueWillMutate",c.P);return c}
    

    Uhhhhhh .....什么?

1 个答案:

答案 0 :(得分:1)

你问了两个问题,所以我会给你两个半答案。

在我们解决您的第一个问题之前,您正在错误地使用knockout observable函数,这会让您感到很头疼。我们来解决这个问题。以下两行代码的工作方式类似。调用observable函数时,将创建一个observable的新实例。如果您在没有参数的情况下调用它,则observable的值为undefined。因为我们知道你想要一个字符串,所以最好将它初始化为空字符串,如第二个例子所示。

name: ko.observable(),

name: ko.observable(''),

然后,我们可以通过将它作为函数调用来设置或检索observable的值:

that.name('value');

that.name() == 'value';

  

我从教程中获得了函数结构。我不知道为什么需要   用IF语句检查长度。什么是返回   到底是什么?

在if语句之后,您有以下代码行:

http.jsonp(url + name + key, 'jsoncallback')

如果名称未定义或为空,您将尝试分别对两个网址之一进行此调用:

https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/undefined/?api_key=#

https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name//?api_key=#

我们知道两者都应该返回错误(可能是400),因此进行这些调用毫无意义。当字符串初始化为空时,if语句应用于字符串时为true。注意,如果字符串是undefined,这将引发错误,这是不好的。

但是,语法也错了。从技术上讲,that.name的值是一个函数,当被视为字符串时,将评估为

function (b){function c(){if(0<arguments.length)return c.Ka(d,arguments[0])&&(c.P(),d=arguments[0],c.O()),this;a.k.zb(c);return d}var d=b;a.N.call(c);a.a.sa(c,a.m.fn);c.o=function(){return d};c.O=function(){c.notifySubscribers(d)};c.P=function(){c.notifySubscribers(d,"beforeChange")};a.s(c,"peek",c.o);a.s(c,"valueHasMutated",c.O);a.s(c,"valueWillMutate",c.P);return c}

回想一下,在if语句中写一个更好的东西是

if (!that.name())

我们调用函数来获取值。 {j}中的''undefined都是 falsey ,因此if语句会捕获这两种情况并退出,这就是我们想要的。请注意,如果name的值为0或任何其他 falsey javascript值,它也会退出。

  

此api调用返回一个内部嵌套对象的JSON对象。什么   我想要的是,将嵌套对象中的键和值显示为   李的观点。现在我甚至不能告诉我它是否   实际上是抓住了对象。

您的观点存在许多问题。

<ul data-bind="foreach: name">

这将迭代that.name的值。如果that.name'ryebrush',那么(我相信)会遍历每个字母。那不好。如果您的目标是在that.name中列出汇总人员,则需要将ko.observableko.observableArray交换。您可能还想将名称that.name更改为that.names以避免混淆。

<li data-bind="text:$data"></li>

这是正确的,如果您的数组填充了字符串。 foreach将迭代数组中的每个项目,$data是每个项目。但是,如果项目实际上是对象,则可以引用该项目的属性。例如,如果数组中的每个项目都是     { “ID”:25500750, “姓名”: “RyeBrush”, “profileIconId”:551, “summonerLevel”:30, “revisionDate”:1426533699000}

然后,由于name是对象的属性,因此您可以在视图中引用name

<li data-bind="text:name"></li>

最后,在http调用之后,您实际上并没有在正确的位置获取数据。如果对您的http呼叫的响应是

{"ryebrush":{"id":25500750,"name":"RyeBrush","profileIconId":551,"summonerLevel":30,"revisionDate":1426533699000}}

然后你想写

return http.jsonp(url + name + key, 'jsoncallback')
    .then(function(response){
        that.name(response["ryebrush"]);
    });

如果响应是项目数组

[{"ryebrush":{"id":25500750,"name":"RyeBrush","profileIconId":551,"summonerLevel":30,"revisionDate":1426533699000}}]

然后你想写

return http.jsonp(url + name + key, 'jsoncallback')
    .then(function(response){
        that.name(response[0]["ryebrush"]);
    });

结论

不幸的是,这不是一个很好的问题。我无法确切知道你正在使用的API究竟发生了什么,所以我无法确切地告诉你应该写什么。要完成你想要做的事情,你需要花一点时间阅读javascript,knockout, durandal。以下是每个人的一些好资源:

但是,我发现你是一个新用户。我想鼓励你不要气馁。学习绳索需要一些时间,但这是值得的。不要放弃。我希望这有帮助!