我正在尝试创建一个模仿here所示功能的简单仪表板。我想要坚持一个棱角分明的构造,但我已经成功地将自己混淆为遗忘。我对Angular一般都是新手。
我正在根据Github API中的数据创建一个简单的仪表板。我想引用以下数据源(其中用户是搜索栏中的值,而 repo 是从回购列表中点击的值 - 请参阅链接示例in第1段):
"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
基本上,应用程序应该按以下方式工作:
用户在搜索栏中输入Github用户名。
进行API调用以返回用户信息和回购列表 (我列出的前两个网址)
到目前为止,我有这个工作。
据我所知,我需要加入Angular承诺,因为我的第3次Get请求未被识别。
有人可以帮我重构我的app.js代码,以确保: - 我有一套" repo"页面渲染(即第一个列出的仓库将被默认选中) - 用户与回购列表交互后再次调用事件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>
修改 这是我看到的错误 - 再次,它们似乎表明我需要实施承诺。然后,我不确定为什么我无法指定默认选定的回购。
可能未经处理的拒绝:{&#34;数据&#34;:{&#34;消息&#34;:&#34;未找到&#34;,&#34; documentation_url&#34;:&#34; https://developer.github.com/v3&#34;}&#34;状态&#34;:404,&#34;配置&#34; {&#34;方法&#34;:&#34; GET&#34 ;, &#34; transformRequest&#34;:[空],&#34; transformResponse&#34;:[空],&#34; jsonpCallbackParam&#34;:&#34;回调&#34;&#34; URL&# 34;:&#34; https://api.github.com/repos/mbostock//events&#34;,&#34;标题&#34;:{&#34;接受&#34;:&#34; application / json,text / plain, / &#34;}},&#34; statusText&#34;:&#34; Not Found&#34;}
更新和修改 通过@mikwat的建议,我尝试使用ng-model来绑定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);
}
});
虽然这是要渲染数据,但我无法弄清楚如何动态地将第一个repo列表值分配为我的默认值(我尝试了document.getElementById("repo1").value
但是我得到了未定义的数据&#39;)AND该函数不会在下拉列表更改时再次调用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);
}
});
答案 0 :(得分:1)
这是一个有效的解决方案。我删除了一些依赖项,只是为了让它在这个沙箱中工作。我使用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>