与杜兰达尔合作的第一个JavaScript项目.尝试从第三方 API 获取数据

First javascript project with Durandal. Trying to get data from 3rd party API

本文关键字:第三方 API 数据 获取 项目 JavaScript 杜兰达 第一个      更新时间:2023-09-26

所以我正在做一个项目,让游戏的玩家能够将他们的表现与相同技能水平的同龄人进行比较。我可以让代码的原型在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 密钥。如有必要,我会提供一个,稍后再更改。

我这里有 2 个具体问题:

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

  2. 此 api 调用返回一个 JSON 对象,其中包含一个嵌套对象。我想要的是将嵌套对象的键和值显示为视图上的 li。现在我什至无法让它告诉我它是否真的首先抓住了物体。

这是我的 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>

我希望看到的只是 1 个项目符号项,其中要么说对象,要么输入输入框中的任何名称。我得到的什么都不是。

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

{"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}

呃呃.....什么?

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

在我们解决您的第一个问题之前,您错误地使用了敲除可观察函数,这将给您带来很多麻烦。让我们解决这个问题。以下两行代码的工作方式类似。调用可观察量函数时,将创建可观察量的新实例。如果不带参数调用它,则可观察量的值为 undefined 。由于我们知道您在这里想要一个字符串,因此最好将其初始化为空字符串,如第二个示例所示。

name: ko.observable(),

name: ko.observable(''),

然后,我们可以通过将其调用为函数来设置或检索可观察量的值:

that.name('value');

that.name() == 'value';

我从教程中获得了函数结构。我不知道为什么我需要 以使用 IF 语句检查长度。那是什么回报 完全?

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

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

如果 name 未定义或为空,您将尝试分别对以下两个 url 之一进行此调用:

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())

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

此 api 调用返回一个 JSON 对象,其中包含一个嵌套对象。什么 我想要的是将嵌套对象的键和值显示为 李在观点上。现在我什至无法让它告诉我它是否 实际上首先抓住了物体。

你的观点有很多问题。

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

这将遍历 that.name 的值。如果that.name'ryebrush',这将(我相信)遍历每个字母。那可不行。如果您的目标是在that.name中拥有召唤师列表,则需要与ko.observableArray交换ko.observable。您可能还希望将名称that.name更改为that.names以避免混淆。

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

如果您的数组填充了字符串,这是正确的。 foreach将循环访问数组中的每个项,每个项$data。但是,如果项实际上是一个对象,则可以引用该项的属性。例如,如果数组中的每个项目都是 {"id":25500750,"name":"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。以下是每个方法的一些好资源:

  • JavaScript
  • 淘汰赛
  • 杜兰达尔

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