gpt4 book ai didi

javascript - 了解 Angular Promise 和 API 调用——从 API 创建用户仪表板

转载 作者:太空宇宙 更新时间:2023-11-04 15:42:50 25 4
gpt4 key购买 nike

我正在尝试创建一个简单的仪表板来模仿显示的功能 here 。我想坚持一个 Angular 结构,但我已经成功地将自己迷失了。总的来说,我对 Angular 还很陌生。

我正在根据 Github API 中的数据创建一个简单的仪表板。我想引用以下数据源(其中 user 是搜索栏中的值,repo 是从存储库列表中单击的值 - 请参阅中的链接示例第一段):

"https://api.github.com/users/" + user                          ----> returns general user info
"https://api.github.com/users/" + user + "/repos" ----> used for repo list
"https://api.github.com/repos/" + user + "/" + repo + "/events" ----> list of events per repo

本质上,该应用程序应该按以下方式工作:

  1. 用户在搜索栏中输入 Github 用户名。

  2. 调用API返回用户信息和仓库列表 (我列出的前两个网址)

到目前为止,我已经完成了这项工作。

  • 然后,根据返回的下拉列表中第一个选定的存储库或选定的值,将调用第三个 URL 以返回更多数据。
  • 据我所知,我需要合并 Angular promise ,因为我的第三个 Get 请求未被识别。

    有人可以帮助我重构我的 app.js 代码以确保:- 我在页面渲染上设置了一个“存储库”(即第一个列出的存储库将是默认选择的)- 用户与存储库列表交互后再次调用事件 API

    我试图遵循所解释的内容here但我对如何合并用户名和选定的存储库有点困惑。如果有人可以指导我如何在代码中添加这些参数(由用户指定),我将非常感激!

    这是我当前的代码,供引用:

    app.js

    angular.module('myApp', ['ui.router'])
    .controller('DashboardCtrl', function($scope, $state, $http){
    // Set search model to 'mbostock' and the fetch function to contact the
    // remote API and ensure the view is initialized. Load results when the search box changes.
    $scope.$watch('search', function() {
    initialFetch();
    });
    $scope.search = "mbostock";


    // Make calls to the API for Users and Repo List
    function initialFetch(){
    $http.get("https://api.github.com/users/" + $scope.search)
    .then(function(response){ $scope.userinfo = response.data; });

    $http.get("https://api.github.com/users/" + $scope.search + "/repos")
    .then(
    function(response){ $scope.repolist = response.data;

    // Create call for events listing based on repo choice
    var repo = "";

    // console.log(document.getElementById("repo1").value);

    $(function() {
    //For showing default url
    MakeUrl();
    // On repository selection, call events
    $('#repo-select').on('change', function () {
    if ($(this).val() == 0) {
    repo = document.getElementById("repo1").value;
    } else {
    repo = $(this).val();
    }
    MakeUrl();
    return false;
    });

    });

    function MakeUrl() {
    var finalUrl = "https://api.github.com/repos/" + $scope.search + "/" + repo + "/events";
    console.log(finalUrl);
    $http.get(finalUrl)
    .then(function (response) { $scope.eventinfo = response.data; });
    }


    });
    }


    // Function select which ensures that the entire
    // text is selected when the user clicks in the text input.
    $scope.select = function(){
    this.setSelectionRange(0, this.value.length);
    }
    })

    index.html

    <body>
    <div class="container-fluid outerdiv" ng-app="myApp" ng-controller="DashboardCtrl">

    <nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container-fluid">
    <div class="navbar-header">
    <a class="navbar-brand"><b>Github User Information</b> <span class="span-style"></span></a>
    </div>

    <div class="input-group search-bar">
    <input type="text" ng-model="search" ng-model-options="{ debounce: 800 }" onclick="select()" class="form-control" placeholder="Enter Github user login" autofocus />
    <span class="input-group-addon bar-style"><i class="glyphicon glyphicon-search"></i></span>
    </div>
    </div>
    </nav>

    <noscript>
    <div class="nojs">Javascript is either disabled or not supported in your browser. Please enable it or use a Javascript enabled browser.</div>
    </noscript>

    <div class="animated zoomInRight">


    <div id="user-bio" class="col-sm-4 col-md-4">
    <div>
    <div class="avatar">
    <img src="{{ userinfo.avatar_url }}" class="thumbnail animated flip movie-poster">
    </div>

    <span class="span-outer">
    <a href="{{userinfo.html_url}}" target="_blank">{{ userinfo.login }}</a>
    </span><br>{{ userinfo.name }}

    <p><strong>Joined:</strong><br> {{ userinfo.created_at }}</p>
    <p><strong>Last Updated:</strong><br> {{ userinfo.updated_at }}</p>

    <p>{{ userinfo.bio }}</p>

    <p class="outer-p">
    <div class="inner-p">
    <span class="label label-primary">Public Repos :</span> {{ userinfo.public_repos }}
    </div>
    <div class="inner-p">
    <span class="label label-primary">Followers :</span> {{ userinfo.followers }}
    </div>
    <div class="inner-p">
    <span class="label label-primary">Following :</span> {{ userinfo.following }}
    </div>
    </p>

    </div>

    <div ng-if="userinfo.message==='Not Found'">
    No results found.
    </div>
    </div>

    <div class="col-sm-8 col-md-8">
    <h5><strong>Repositories:</strong></h5>
    <select id="repo-select">
    <option ng-repeat="repo in repolist" id="repo{{ $index + 1 }}" value="{{ repo.name }}" onchange="MakeUrl();">{{ repo.name }}</option>
    </select>

    <h5><strong>Events:</strong></h5>
    <ul class="event-results" id="event-select" style="height:400px; overflow-y:auto;">
    <li ng-repeat="event in eventinfo">
    <a id="{{ $index + 1 }}" value="{{ event.type }}">{{ event.type }}
    </a>, {{ event.created_at }} <!--ng-click="update(movie)"-->
    </li>
    </ul>
    </div>

    </div>
    </div>

    </body>

    编辑这是我看到的错误 - 再次,它们似乎表明我需要实现 promise 。话又说回来,我不确定为什么我不能指定默认选择的存储库。

    可能未处理的拒绝:{"data":{"message":"Not Found","documentation_url":"https://developer.github.com/v3 "},"status":404,"config":{"method":"GET ","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"回调","url":"https://api.github.com/repos/mbostock//events ","headers":{"Accept":"application/json, text/plain,/"}},"statusText":"未找到"}

    更新和编辑通过 @mikwat 的建议,我尝试使用 ng-model 绑定(bind) repo 变量。

    我的新 app.js 文件如下所示:

    angular.module('myApp', ['ui.router'])
    .controller('DashboardCtrl', function($scope, $state, $http, DataService){
    // Set search model to 'mbostock' and the fetch function to contact the
    // remote API and ensure the view is initialized. Load results when the search box changes.
    $scope.$watch('search', function() {
    initialFetch();
    // .then(MakeUrl);
    });

    var user = $scope.search;
    $scope.search = "mbostock";
    $scope.repo = "array-source";


    // Make calls to the API for Users and Repo List
    function initialFetch(){
    $http.get("https://api.github.com/users/" + $scope.search)
    .then(function(response){ $scope.userinfo = response.data; });

    $http.get("https://api.github.com/users/" + $scope.search + "/repos")
    .then(
    function(response){ $scope.repolist = response.data; },
    $http.get("https://api.github.com/repos/" + $scope.search + "/" + $scope.repo + "/events")
    .then(function (response) { $scope.eventinfo = response.data; })
    );
    }


    // Function select which ensures that the entire
    // text is selected when the user clicks in the text input.
    $scope.select = function(){
    this.setSelectionRange(0, this.value.length);
    }
    });

    虽然这是获取要渲染的数据,但我无法弄清楚如何动态分配第一个存储库列表值作为我的默认值(我尝试了 document.getElementById("repo1").value 但我得到“未定义”)并且该函数不会在下拉列表更改时再次调用 API。

    更新 5/5/2017 -- 个人解决方案非常感谢@mikwat 提供的所有帮助。我最终使用了与他下面稍有不同的解决方案,但两者都有效。

    angular.module('myApp', [])
    .controller('DashboardCtrl', function($scope, $http){
    // Set search model to 'mbostock' and the fetch function to contact the
    // remote API and ensure the view is initialized. Load results when the search box changes.
    $scope.$watch('search', function() {
    initialFetch();
    // .then(MakeUrl);
    });

    // NOTE: watch for changes to repo
    $scope.$watch('repo', function() {
    $http.get("https://api.github.com/repos/" + $scope.search + "/" + $scope.repo + "/events")
    .then(function (response) {
    $scope.eventinfo = response.data;
    });

    });

    var user = $scope.search;
    $scope.search = "mbostock";

    // Make calls to the API for Users and Repo List
    function initialFetch(){
    $http.get("https://api.github.com/events")
    .then(function(response){ $scope.publicevents = response.data; console.log(response.data);})
    .catch(function (err) {
    console.log(err)
    });

    $http.get("https://api.github.com/users/" + $scope.search)
    .then(function(response){ $scope.userinfo = response.data; })
    .catch(function (err) {
    console.log(err)
    });

    $http.get("https://api.github.com/users/" + $scope.search + "/repos")
    .then(
    function(response){
    $scope.repolist = response.data;

    // NOTE: select first repo
    if ($scope.repolist && $scope.repolist.length > 0) {
    var repo = $scope.repolist[0].name;
    } else {
    console.log("Something went wrong here!");
    var repo = "undefined"
    }
    $scope.repo = repo;
    return repo
    }).then(function (repo) {
    $http.get("https://api.github.com/repos/" + $scope.search + "/" + repo + "/events")
    .then(function (response) { $scope.eventinfo = response.data; console.log(response.data);})
    return repo;
    }).then(function (repo) {
    $http.get("https://api.github.com/repos/" + $scope.search + "/" + repo + "/languages")
    .then(function (response) { $scope.languages = response.data; console.log(response.data);})
    }).catch(function (err) {
    console.log("Here!" + err);
    });
    };


    // Function select which ensures that the entire
    // text is selected when the user clicks in the text input.
    $scope.select = function(){
    this.setSelectionRange(0, this.value.length);
    }


    });

    最佳答案

    这是一个可行的解决方案。我删除了一些依赖项只是为了让它在这个沙箱中工作。我用过NOTE:评论以帮助描述重要的变化。

    angular.module('myApp', [])
    .controller('DashboardCtrl', function($scope, $http){
    // Set search model to 'mbostock' and the fetch function to contact the
    // remote API and ensure the view is initialized. Load results when the search box changes.
    $scope.$watch('search', function() {
    initialFetch();
    // .then(MakeUrl);
    });

    // NOTE: watch for changes to repo
    $scope.$watch('repo', function() {
    $http.get("https://api.github.com/repos/" + $scope.search + "/" + $scope.repo + "/events")
    .then(function (response) {
    $scope.eventinfo = response.data;
    });

    // NOTE: additional request to fetch languages
    $http.get("https://api.github.com/repos/" + $scope.search + "/" + $scope.repo + "/languages")
    .then(function (response) {
    console.log(response.data);
    // TODO: display results
    });

    });

    var user = $scope.search;
    $scope.search = "mbostock";

    // Make calls to the API for Users and Repo List
    function initialFetch(){
    $http.get("https://api.github.com/users/" + $scope.search)
    .then(function(response){ $scope.userinfo = response.data; });

    $http.get("https://api.github.com/users/" + $scope.search + "/repos")
    .then(
    function(response){
    $scope.repolist = response.data;

    // NOTE: select first repo
    if ($scope.repolist && $scope.repolist.length > 0) {
    $scope.repo = $scope.repolist[0].name;
    }
    },
    $http.get("https://api.github.com/repos/" + $scope.search + "/" + $scope.repo + "/events")
    .then(function (response) { $scope.eventinfo = response.data; })
    );
    }


    // Function select which ensures that the entire
    // text is selected when the user clicks in the text input.
    $scope.select = function(){
    this.setSelectionRange(0, this.value.length);
    }
    });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

    <div class="container-fluid outerdiv" ng-app="myApp" ng-controller="DashboardCtrl">

    <nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container-fluid">
    <div class="navbar-header">
    <a class="navbar-brand"><b>Github User Information</b> <span class="span-style"></span></a>
    </div>

    <div class="input-group search-bar">
    <input type="text" ng-model="search" ng-model-options="{ debounce: 800 }" onclick="select()" class="form-control" placeholder="Enter Github user login" autofocus />
    <span class="input-group-addon bar-style"><i class="glyphicon glyphicon-search"></i></span>
    </div>
    </div>
    </nav>

    <noscript>
    <div class="nojs">Javascript is either disabled or not supported in your browser. Please enable it or use a Javascript enabled browser.</div>
    </noscript>

    <div class="animated zoomInRight">


    <div id="user-bio" class="col-sm-4 col-md-4">
    <div>
    <div class="avatar">
    <img src="{{ userinfo.avatar_url }}" class="thumbnail animated flip movie-poster">
    </div>

    <span class="span-outer">
    <a href="{{userinfo.html_url}}" target="_blank">{{ userinfo.login }}</a>
    </span><br>{{ userinfo.name }}

    <p><strong>Joined:</strong><br> {{ userinfo.created_at }}</p>
    <p><strong>Last Updated:</strong><br> {{ userinfo.updated_at }}</p>

    <p>{{ userinfo.bio }}</p>

    <p class="outer-p">
    <div class="inner-p">
    <span class="label label-primary">Public Repos :</span> {{ userinfo.public_repos }}
    </div>
    <div class="inner-p">
    <span class="label label-primary">Followers :</span> {{ userinfo.followers }}
    </div>
    <div class="inner-p">
    <span class="label label-primary">Following :</span> {{ userinfo.following }}
    </div>
    </p>

    </div>

    <div ng-if="userinfo.message==='Not Found'">
    No results found.
    </div>
    </div>

    <div class="col-sm-8 col-md-8">
    <h5><strong>Repositories:</strong></h5>

    <!-- NOTE: use ng-model and ng-repeat and don't clobber repo variable on scope -->
    <select id="repo-select" ng-model="repo">
    <option ng-repeat="r in repolist" id="repo{{ $index + 1 }}" ng-value="r.name" onchange="MakeUrl();">{{ r.name }}</option>
    </select>

    <h5><strong>Events:</strong></h5>
    <ul class="event-results" id="event-select" style="height:400px; overflow-y:auto;">
    <li ng-repeat="event in eventinfo">
    <a id="{{ $index + 1 }}" value="{{ event.type }}">{{ event.type }}
    </a>, {{ event.created_at }} <!--ng-click="update(movie)"-->
    </li>
    </ul>
    </div>

    </div>
    </div>

    关于javascript - 了解 Angular Promise 和 API 调用——从 API 创建用户仪表板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43750391/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com