Angular Firebase (AngularFire) CRUD 显示和编辑页面?

问题描述 投票:0回答:4

为了学习 AngularFire,我正在尝试构建一个简单的 CRUD 应用程序。 INDEX 和 NEW 页面进展顺利,但我被困在 SHOW 和 EDIT 页面上。我无法在 SHOW 页面上显示选定的记录。

使用 MongoDB 和 Angular 可以轻松制作 SHOW 页面。在 INDEX 页面上,您放入一个锚链接,其中包含您要显示的记录的 ID:

<a ng-href="#/{{record._id}}"><span>{{record.title}}</span<</a>

这会将记录 ID 放入 URL,例如

www.website.com/#/K9hr32rhror

然后在 SHOW 页面上您可以使用

{{record.title}}
{{record.author}}
或任何您想要的。 Angular 会神奇地记住您在 INDEX 页面上单击的记录的 ID。我不知道 Angular 是如何做到这一点的。 :-)

在 MongoDB 中,ID 称为

_id
。在 Firebase 中,该 ID 称为
$id
。所以我将INDEX页面上的代码更改为

<a ng-href="#/{{record.$id}}"><span>{{record.title}}</span<</a>

这成功地将 ID 放入 URL 中。

问题是SHOW页面没有显示任何记录。 Angular 似乎忘记了

{{record}}
指的是什么。

我尝试输入领先

/

<a ng-href="/#/{{record._id}}"><span>{{record.title}}</span<</a>

这没有什么区别。

我尝试使用

从 URL 解析 ID
var key = location.hash.split('#/')[1]

这将返回 ID。当我 console.log $firebaseArray(ref) 对象时,我看到所有记录的集合(数组)。但是当我使用

collection.$getRecord(key)
collection.$keyAt(0)
collection.$indexFor(key)
时,我得到 null 或 -1,表明 AngularFire 找不到记录。

这是我的完整控制器代码:

app.controller('ShowController', ['$scope', '$firebaseArray', '$location',
function($scope, $firebaseArray, $location) {

var ref = new Firebase("https://my-firebase.firebaseio.com/");
list = $firebaseArray(ref);
console.log(list); // []
console.log(location.hash.split('#/')[1]); // -K9hr32rhror_
var key = location.hash.split('#/')[1];
console.log(list.$getRecord(key)); // null
console.log(list.$keyAt(0)); // null
console.log(list.$indexFor(key)); // -1

接下来我尝试使用

ng-repeat="record in collection | filter : key">
但我不知道
key
应该是什么。

我还用 google 搜索了“Angular Firebase CRUD SHOW 页面”,但示例 CRUD 应用程序都没有 SHOW 页面。我是否误解了一些基本的东西?例如,我应该在 INDEX 页面上使用

<ng-hide>
<ng-show>
构建 SHOW 和 EDIT 视图,而不费心制作单独的 SHOW 和 EDIT 页面吗?

javascript angularjs firebase crud angularfire
4个回答
3
投票

您正在处理的问题是异步数据流。

app.controller('ShowController', ['$scope', '$firebaseArray', '$location',
function($scope, $firebaseArray, $location) {
  var ref = new Firebase("https://my-firebase.firebaseio.com/");
  var key = location.hash.split('#/')[1];
  $scope.list = $firebaseArray(ref); // data is downloading
  console.log($scope.list.length); // will be undefined, data is downloading
  $scope.list.$loaded().then(function(list) {
    console.log(list); // data has been downloaded!
    list.$getRecord(key); // data is available
  });
});

但是

.$loaded()
通常是不必要的,因为 AngularFire 知道何时触发
$digest
。在您的情况下,您想使用
$firebaseObject

app.controller('ShowController', ['$scope', '$firebaseObject', '$location',
function($scope, $firebaseObject, $location) {
  var ref = new Firebase("https://my-firebase.firebaseio.com/");
  var key = location.hash.split('#/')[1];
  var itemRef = ref.child(key);
  $scope.item = $firebaseObject(itemRef); 
});

这会根据

key
抓取单个项目,而不是下载整个列表并取出一个项目。


1
投票

谢谢 David East,问题是异步数据。这是两个工作控制器。第一个控制器获取数据数组并从数组中选择我想要的记录:

app.controller('ShowController', ['$scope', '$firebaseArray', '$location',
function($scope, $firebaseArray, $location) {
  // set up Firebase
  var ref = new Firebase("https://my-firebase.firebaseio.com/"); // goes to Firebase URL (fbURL)
  var list = $firebaseArray(ref); // puts
  list.$loaded().then(function(x) { // promise that executes when asynchronous data has loaded
    var key = location.hash.split('#/')[1]; // parses key from URL query string
    var showItem = list.$getRecord(key); // gets the record using the key passed in from the URL query string
    var showItems = []; // make an array
    showItems.push(showItem); // push the record into the array
    $scope.showItems = showItems; // attach the array to $scope
    // now 'ng-repeat="showIdea in showIdeas"' will iterate through the array, which has only one element
    // i.e., this is how you make Angular display one thing
  })
  .catch(function(error) { // if the data doesn't load
    console.log("Error:", error);
  });
}]);

第二个控制器使用 David East 的建议,即使用

$firebaseObject
仅下载我想要的记录。我添加了一些代码以使其使用
ng-repeat
显示。还有另一种方法可以用 Angular 显示单个记录吗?

app.controller('ShowController', ['$scope', '$firebaseObject', '$location',
function($scope, $firebaseObject, $location) {
  // set up Firebase
  var ref = new Firebase("https://my-firebase.firebaseio.com/"); // goes to Firebase URL (fbURL)
  var key = location.hash.split('#/')[1]; // parses key from URL query string
  var itemRef = ref.child(key); // sets up the query
  var showItems = []; // make an array
  showItems.push($firebaseObject(itemRef)); // makes the query and push the record into the array
  $scope.showItems = showItems; // attach the array to $scope
}]);

这是观点:

<table ng-repeat="showItem in showItems">
  <tr><td>Name:</td><td>{{showItem.itemName}}</td></tr>
  <tr><td>Title:</td><td>{{showItem.itemTitle}}</td></tr>
</table>

0
投票

以简单的方式和形式进行 Angular firebase crud https://youtu.be/Ao4sdagqpvg


0
投票
    import { Injectable } from "@angular/core";
import { AngularFirestore } from "@angular/fire/firestore";
import User from "../models/user-model.model";

@Injectable({
  providedIn: "root",
})
export class FireStoreService {
  constructor(private _db: AngularFirestore) {
    fireStore = this;
  }
   
  public async userDataById(uid: string) {
    const userSnap = await this._db.doc(`users/${uid}`).get().toPromise();
    return userSnap.data();
  } 
  
  public async createUser(_id : string,userModel : User) {
    try {
      //Generate Firebase Id for New Node
      //Push User Data in that Node
      return this._db.collection('/User/').doc(_id).set({
        isDelete: userModel.isDelete,
        isActive: userModel.isActive
      });
    } catch(error) {
      console.log(error)
      return null;
    }
  }  
   
  public async getUsersListing() {
    try {
      // Query to get users where isDelete is false and isActive is true
      const usersListingSnapshot = await this._db.firestore.collection("/User/")
        .where("isDelete", "==", false)
        .where("isActive", "==", true) 
        .get();
      
      // Mapping the documents to data
      const usersListings = usersListingSnapshot.docs.map((doc) => doc.data());
      
      return usersListings;
    } catch (error) {
      console.error('Error getting user listings:', error);
      return null;
    }
  }
  
    
  public async getCaptionDetailsById(Id: string) {
    try { 
      const querySnapshot = (await this._db.firestore.collection("/User/").get()).docs
        .filter((doc) => doc.id === Id)
        .map((doc) => doc.data());
      return querySnapshot;
    } catch (error) {
      return null;
    }
  }

  
  public async updateUserDetails(userModel: UserModel): Promise<boolean> {
    try {
      const result = await this._db.collection('/User/').doc(userModel.id).update({
        name: userModel.name,
        number: userModel.number,
        gender: userModel.gender,
        isVerify: userModel.isVerify,
        updateAt: userModel.updateAt,
        photo: userModel.photo,
      });
  
      return true;
    } catch (error) {
      console.error('Error updating user details:', error);
      return false;
    }
  }
  
  

  public async deleteData(id: string): Promise<Boolean> {
    try {
        // Mark the document as deleted instead of actually deleting it
        await this._db.collection('/RouteMaster/').doc(id).update({ isDelete: true,  isActive: false   });
        console.log(`Document with ID ${priceId} marked as deleted successfully`);
        return true;
    } catch (error) {
        console.error('Error marking document as deleted:', error);
        return false;
    }
}
  
  
}
© www.soinside.com 2019 - 2024. All rights reserved.