[英]AngularJS application: unable to update $index
I am working on an app in AngularJS 1.6, using the Giphy.com api. 我正在使用Giphy.com api在AngularJS 1.6中开发应用程序。
There is a Plunker HERE . 有一个Plunker 这里 。
I iterate over an array of "giphys"coming from https://api.giphy.com/v1/gifs/trending?api_key=myApyKey
and display them into Bootstrap 4 cards. 我迭代了来自https://api.giphy.com/v1/gifs/trending?api_key=myApyKey
的一系列“giphys”,并将它们显示在Bootstrap 4卡中。
There is a view single giphy functionality . 有一个视图单giphy功能 。 In the controller I have: 在控制器中我有:
// Create controller for the "giphyApp" module
app.controller("giphyCtrl", ["$scope", "$http", "$filter", "$timeout", function($scope, $http, $filter, $timeout) {
var url = "https://api.giphy.com/v1/gifs/trending?api_key=PTZrBlrq8h2KUsRMeBuExZ5nHyn7dzS0&limit=120&rating=G";
$scope.giphyList = [];
$scope.search = "";
$scope.filterList = function() {
var oldList = $scope.giphyList || [];
$scope.giphyList = $filter('filter')($scope.giphys, $scope.search);
if (oldList.length != 0) {
$scope.pageNum = 1;
$scope.startAt = 0;
};
$scope.itemsCount = $scope.giphyList.length;
$scope.pageMax = Math.ceil($scope.itemsCount / $scope.perPage);
};
$http.get(url)
.then(function(data) {
// giphy arary
$scope.giphys = data.data.data;
$scope.filterList();
console.log($scope.giphys);
// Paginate
$scope.pageNum = 1;
$scope.perPage = 24;
$scope.startAt = 0;
$scope.filterList();
$scope.currentPage = function(index) {
$("html, body").animate({
scrollTop: 0
}, 500);
$timeout( function(){
$scope.pageNum = index + 1;
$scope.startAt = index * $scope.perPage;
},0);
};
$scope.prevPage = function() {
if ($scope.pageNum > 1) {
$scope.pageNum = $scope.pageNum - 1;
$scope.startAt = ($scope.pageNum - 1) * $scope.perPage;
}
};
$scope.nextPage = function() {
if ($scope.pageNum < $scope.pageMax) {
$scope.pageNum = $scope.pageNum + 1;
$scope.startAt = ($scope.pageNum - 1) * $scope.perPage;
}
};
$scope.selectedIndex = null;
$scope.selectedGiphy = null;
$scope.fetchSinglegGiphy = function(giphy, index) {
console.log(index);
$scope.selectedIndex = index;
$scope.selectedGiphy = giphy;
}
});
}]);
The Grid 网格
<div class="row grid" ng-if="giphyList.length > 0">
<div data-ng-repeat="giphy in giphyList | limitTo : perPage : startAt"
class="col-xs-12 col-sm-6 col-lg-4 col-xl-3 d-flex mb-4">
<div class="giphy d-flex flex-column w-100">
<div class="thumbnail pb-2 text-center" data-toggle="modal"
data-target="#giphyModal"
ng-click="fetchSinglegGiphy(giphy, $index)">
<img ng-src="{{giphy.images.downsized.url}}" class="img-fluid">
</div>
<div class="text mt-auto">
<p class="m-0 meta">{{giphy.import_datetime | dateParse | date : "MMMM dd y" }}</p>
<p class="rating m-0">
<i class="fa fa-star" aria-hidden="true"></i> {{giphy.rating | capitalize}}
</p>
<ul class="list-unstyled mb-0 text-center">
<li ng-if="giphy.username != ''" class="text-muted">{{giphy.type | capitalize}} file uploaded by
<br><strong>{{giphy.username | capitalize }}</strong>
</li>
<li ng-if="giphy.username == ''" class="text-muted">{{giphy.type | capitalize}} file uploaded by
<br> <strong>Unknown</strong>
</li>
<li class="h6">{{giphy.title | titlecase }}</li>
</ul>
</div>
</div>
</div>
</div>
<div class="modal fade" id="giphyModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title h-3">{{selectedGiphy.title | titlecase }}</h4>
<button type="button" class="close" data-dismiss="modal">
<span>×</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-12">
<div class="image image text-center">
<img ng-src="{{selectedGiphy.images.original.url}}"
alt="{{selectedGiphy.title }}" class="img-fluid">
</div>
</div>
</div>
</div>
<div class="modal-footer justify-content-between">
<div class="text-muted">Image ID: {{selectedGiphy.id}}</div>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-success" data-dismiss="modal">
<i class="fa fa-times-circle"></i> Close
</button>
</div>
</div>
</div>
</div>
</div>
This part of the application works fine. 这部分应用程序运行正常。
I had expected to be able to easily add a next and previous giphy to the modal above: 我本来希望能够轻松地将下一个和之前的giphy添加到上面的模式中:
<div class="controls text-center">
<a href="#" ng-click="fetchSinglegGiphy(giphy, $index = $index - 1)" class="left">
<i class="fa fa-chevron-left"></i>
</a>
<a href="#" ng-click="fetchSinglegGiphy(giphy, $index = $index + 1)" class="right">
<i class="fa fa-chevron-right"></i>
</a>
</div>
To my surprise this does not work. 令我惊讶的是,这不起作用。 When I click any one of the controls, the GIF file remains the same, wile all the text in the modal disappears. 当我单击任何一个控件时,GIF文件保持不变,并且模式中的所有文本都会消失。
Questions: 问题:
When I click any one of the controls, the GIF file remains the same 当我单击任何一个控件时,GIF文件保持不变
Check to see if giphy
equals what you expect: 检查giphy
等于你的期望:
$scope.fetchSinglegGiphy = function(giphy, index) {
$scope.selectedIndex = index;
$scope.selectedGiphy = giphy;
if ( giphy != $scope.giphyList[index] ) {
$scope.selectedGiphy = $scope.giphyList[index];
};
};
Update the selectedGiphy
in the case that it is not. 更新selectedGiphy
,如果不是。
You not only use $index outside of the ng-repeat block, but also you use giphy outside of that block, where it is not defined. 你不仅可以在ng-repeat块之外使用$ index,而且还可以在该块之外使用giphy,而不是定义它。
I assume you have $scope.giphyList defined in your controller. 我假设您在控制器中定义了$ scope.giphyList。 So all you have to do is to send the index. 所以你要做的就是发送索引。
$scope.selectedIndex = null;
$scope.selectedGiphy = null;
$scope.fetchSinglegGiphy = function(index) {
$scope.selectedIndex = index;
$scope.selectedGiphy = $scope.giphyList[index];
}
<div class="controls text-center">
<a href="#" ng-click="fetchSinglegGiphy(selectedIndex-1)" class="left">
<i class="fa fa-chevron-left"></i>
</a>
<a href="#" ng-click="fetchSinglegGiphy(selectedIndex+1)" class="right">
<i class="fa fa-chevron-right"></i>
</a>
</div>
I hope this helps, Cheers 干杯,我希望这会有所帮助
index.html 的index.html
<div class="modal fade" id="giphyModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="controls text-center">
<a href="#" ng-click="fetchSinglegGiphyModal('prev')" class="left"><i class="fa fa-chevron-left"></i></a>
<a href="#" ng-click="fetchSinglegGiphyModal('next')" class="right"><i class="fa fa-chevron-right"></i></a>
</div>
<div class="modal-header">
<h4 class="modal-title h-3">
{{ selectedGiphy.title | capitalize }}
</h4>
<button type="button" class="close" data-dismiss="modal">
<span>×</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-12">
<div class="image image text-center">
<img ng-src="{{ selectedGiphy.images.original.url }}" alt="{{ selectedGiphy.title }}" class="img-fluid" image-on-load ng-hide="modalImageLoading" />
<div class="spinner-border" ng-if="modalImageLoading"></div>
</div>
</div>
</div>
</div>
<div class="modal-footer justify-content-between">
<div class="text-muted">
Image ID: {{ selectedGiphy.id }}
</div>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-success" data-dismiss="modal">
<i class="fa fa-times-circle"></i> Close
</button>
</div>
</div>
</div>
</div>
</div>
MODIFICATIONS: 改进:
<a href="#" ng-click="fetchSinglegGiphyModal('prev')" class="left"><i class="fa fa-chevron-left"></i></a>
<a href="#" ng-click="fetchSinglegGiphyModal('next')" class="right"><i class="fa fa-chevron-right"></i></a>
fetchSinglegGiphyModal
handles both previous and next Giphy based on the condition that acts on the argument prev
or next
value that we pass in the function. fetchSinglegGiphyModal
根据作用于我们在函数中传递的参数prev
或next
值的条件处理前一个和下一个Giphy 。
I have also added the following code to introduce loader which comes with bootstrap to indicate that GIF image is being loaded in the background. 我还添加了以下代码来介绍带有引导程序的加载程序,以指示GIF图像正在后台加载。
<div class="image image text-center">
<img ng-src="{{ selectedGiphy.images.original.url }}" alt="{{ selectedGiphy.title }}" class="img-fluid" image-on-load ng-hide="modalImageLoading" />
<div class="spinner-border" ng-if="modalImageLoading"></div>
</div>
app.js app.js
$scope.modalImageLoading = false;
$scope.fetchSinglegGiphy = function (giphy, index) {
$scope.selectedIndex = index;
$scope.selectedGiphy = giphy;
$scope.modalImageLoading = true;
};
$scope.fetchSinglegGiphyModal = function (dir) {
let selectedGiphy = null;
if (dir === "prev") $scope.selectedIndex -= 1; // To load previous
else if (dir === "next") $scope.selectedIndex += 1; // To load next
selectedGiphy = $scope.giphyList[$scope.selectedIndex];
if (selectedGiphy) {
$scope.selectedGiphy = selectedGiphy;
$scope.modalImageLoading = true;
}
};
$scope.fetchSinglegGiphyModal
acts on the condition we pass in the parameter and shows the corresponding Giphy data. $scope.fetchSinglegGiphyModal
作用于我们在参数中传递的条件并显示相应的Giphy数据。
I have implemented a custom directive to show the image element and hide the loader when the image is downloaded. 我已经实现了一个自定义指令来显示图像元素并在下载图像时隐藏加载器。 Here is the directive code: 这是指令代码:
app.directive('imageOnLoad', function () {
return {
restrict: 'A',
controller: 'giphyCtrl',
link: function (scope, element, attrs) {
element.bind('load', function () {
scope.$apply(function () {
scope.modalImageLoading = false;
});
});
}
}
});
Here is the modified plunker code . 这是修改后的plunker 代码 。
Hope it helps! 希望能帮助到你!
Where you move the giphy to the modal, you should also send the $index (as you really did), so in the modal you know who your index is, regardless of $index. 如果你将giphy移动到模态,你也应该发送$ index(就像你真的那样),所以在模态中你知道你的索引是谁,而不管$ index。
<div class="controls text-center">
<a href="#" ng-click="fetchSinglegGiphy(giphy, selectedIndex - 1)" class="left"><i class="fa fa-chevron-left"></i></a>
<a href="#" ng-click="fetchSinglegGiphy(giphy, selectedIndex + 1)" class="right"><i class="fa fa-chevron-right"></i></a>
</div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.