我的应用程序是使用AngularJS,Yeoman堆栈,连接到Firebase,AngularFire数据库构建的。在我的应用程序中,我正在尝试上传和删除图片,如下所示
它工作正常,除非我删除其他图像之间的任何imgs它实际上不删除img但用宽度和高度为0的img替换它...或者它似乎(更多信息在底部)
如果我删除另一个" in-bewteen" img同样的交易
只有当我删除最外层的img时,该页面才真正删除了imgs。
^^注意顶行上另外两个图像之间的图像是如何删除的,因为它是通过其他img对象水平包围的。我不得不使用firebase。将底部的两个img移除到我首先删除的那个的右边,然后才删除整个底行。
我不知道为什么我会收到这个错误,有人能给我一些反馈吗?
这是我的控制器中的deleteImg和updateImg函数
angular.module('myApp').controller('MainCtrl', ['$scope', '$firebase', '$filter', function($scope, $firebase, $filter) {
$scope.deleteImg = function(img) {
if (confirm('Are you sure you want to delete the img?') === true) {
var deletingID = img.id;
var deletingLink = fireRef + "/" + img.id;
var deleteRef = new Firebase(deletingLink);
deleteRef.remove();
$(".delete").remove();
location.reload();
}
};
$scope.updateImg = function(Img) {
if (confirm('Are you sure you want to update the Img?') === true) {
var updatingID = $scope.selectedImg.id;
var updatingLink = fireRef + "/" + $scope.selectedImg.id;
var updateRef = new Firebase(updatingLink);
var dataObject = {
"name" : $scope.selectedImg.name, "description": $scope.selectedImg.description, "type": $scope.selectedImg.type ... etc...
};
updateRef.set(dataObject);
location.reload();
}
};
}]);
以下是我实例化我的数组和Firebase数据库以及创建新的$ scope.selectedImg的方法。我目前正在从firebase数据库中获取数据并实例化Img对象数组。我在应用程序中使用该数组作为我的img模型。
var fireRef = new Firebase('MY_FIREBASE_URL');
$scope.imgs = []; //<<< instantiate a new array
var imgNum = 0;
var toArrayFirebaseLink = fireRef + '/' + imgNum;
fireRef.once('value', function(allSnapshot) {
allSnapshot.forEach(function(imgSnapshot) {
var i = imgSnapshot.child('id').val();
if( i !== null ){
// set databaseSnapshot to our img array
$scope.imgs[i] = imgSnapshot.val();
}
});
});
$scope.instantiateImg = function(object) {
$scope.selectedImg = {};
// $scope.selectedImg.name = "";
$scope.selectedImg.etc = "";
$scope.selectedImg.etc = "";
};
//Created selectedImg with data retrieved from database to be used within the views.
$scope.selectImg = function(object) {
$scope.selectedImg = object;
};
这是我的html视图
<div class="container">
<div class="col-xs-6 col-sm-4 col-md-4 col-lg-3 campaign-thumbs" ng-repeat="img in imgs track by $index" ng-animate="'animate'">
<button type="button" class="delete" ng-click="deleteImg(img)">
<span>×</span>
<span class="sr-only">Delete</span>
</button>
<img ng-click="selectImg(img)" src="{{img.imgSrc}}" class="img-responsive" data-toggle="modal" data-target="#imgModal">
</div>
</div>
使用chrome AngularJS扩展我发现我使用firebase remove()函数在数据库中删除了元素,我的$ scope.imgs数组仍然有一个&#34; null&#34;我删除它的空间中的元素。见下图
如何解决此错误?
EDIT1:
我按照@ m.e.conroy的建议添加了拼接功能并认为它工作得很好,特别是因为我删除了location.reload()
并且在视图中它显示图片被删除而没有刷新。但是,当我刷新页面时,同样的&#34;鬼&#34; imgs及其删除按钮再次出现。
当我检查范围模型的AngularJS chrome扩展时,它显示最外面的img(&#34之间的img;中间&#34; ghost imgs)正在接管已删除的图像,意味着删除的图像被设置为具有相同的名称,id和最外部img对象的其他属性。再一次,根据chrome扩展,阵列元素不会被移除,而只是被替换。一旦我刷新它然后回到我以前的&#34; null&#34;数组中的元素。这很奇怪,因为在我的Firebase仪表板中,它显示imgs确实被删除但是在删除最外层的img之前它不会反映在我的视图中。以下是我的Firebase信息中心和索引的视图。仅当删除img 24时,实际上才会应用更改。
EDIT2:
正如@katowulf在本文中所引用的那样(https://www.firebase.com/blog/2014-04-28-best-practices-arrays-in-firebase.html),我遇到了他在&#34;在数组中存储数据的好用例&#34;中描述的确切问题。部分。目前,我试图在我删除的每个imgs之后定位每个imgs,并将其ID更改为id - 1
以及将火灾中的imgs位置改为firebar_url/ref - 1
但我感觉像我试图强制实施而不是找到正确的解决方案。我应该尝试重构我的代码以利用他建议的对象吗? (我最初尝试过,但是我无法抓取对象,因此它的属性必须依靠firebase快照来实例化和创建我的数组。参考:How would I convert my new Object data I am retrieving from Firebase into the JSON form as I had before)。欢迎任何反馈。
我的解决方案:手动更改索引值以及相应的ID&#39;对于已删除的所有img对象,属性为-1。
$scope.deleteImg = function(index, img) {
if (confirm('Are you sure you want to delete the Img?') === true) {
$scope.imgs.splice(index,1); //remove objects in array
var i;
for(i = index; i < $scope.imgs.length; i++) {
//I want to grab the next img object
var previousIndexID = i; //start from the picture right after the one deleted and change its id to id-1
var newIndexID = i+1;
var previousIndexLink = fireRef + "/" + previousIndexID;
var newIndexLink = fireRef + "/" + newIndexID;
var previousIndexRef = new Firebase(previousIndexLink);
var newIndexRef = new Firebase(newIndexLink);
var idIndexLink = fireRef + "/" + previousIndexID + "/id";
var idIndexRef = new Firebase(idIndexLink);
console.log(previousIndexRef.toString()); // element[index] that got deleted
console.log(newIndexRef.toString()); // element[index] next img object
//copy the next img object into the location of the object that just got removed() 'url/num-1' and 'url/id' value
newIndexRef.once('value', function(snap) {
var i = snap.val();
previousIndexRef.set(i);
});
idIndexRef.once('value', function(snap) {
var i = snap.val();
idIndexRef.set(i-1);
});
};
// until the length is reached and then I want it to delete the last one
var lengthID = $scope.imgs.length;
var lengthLink = fireRef + "/" + lengthID;
var lengthRef = new Firebase(lengthLink);
lengthRef.remove();
}
};
下次我肯定会使用服务/对象样式,但对于这个应用程序,这非常有用。无论如何解决它很有趣:)感谢所有帮助@Kato和@ m.e.conroy
答案 0 :(得分:1)
您需要为ng-click
创建一个方法,从$index
传递ng-repeat
,然后在ng-click
调用的控制器方法中删除数组中的图像当用户确认后,然后将其从数据库中删除。从数组中删除它将自动触发ng-repeat
重新渲染。
目前您正在使用jQuery从DOM中删除对象,但它仍然存在于Angular数组中。 Angular并不知道您使用jQuery从视图中删除对象。如果您执行上述操作,您甚至不需要使用jQuery或操作DOM,Angular将为您执行此操作。你也不必做$location.reload
。
$scope.deleteImg = function(i,id){
if(confirm('..') === true){
$scope.imgs.splice(i,1);
// do firebase deletion
}
};
在模板中:
<button type="button" class="delete" ng-click="deleteImg($index,img.id)">
...
</button>
修改强>
实际上,您只需要将$index
参数传递给方法,因为splice会返回已删除的元素,而这将是您的图像对象。即:
$scope.deleteImg = function(i){
var _img = $scope.imgs.splice(i,1);
// use _img.id with your firebase delete statement
};
然后模板只是:
<button type="button" class="delete" ng-click="deleteImg($index)">...
答案 1 :(得分:0)
不确定什么是Firebase,但据我了解你删除了数组中的项目,它变为null。你需要.splice()$ scope.imgs数组才能真正从ng Repeat中删除一个项目