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

Angular Firebase (AngularFire) CRUD SHOW and EDIT pages?

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

有了MongoDB和Angular,制作SHOW页面就很容易了。在 INDEX 页面上,您在锚点 link 中放置了您要显示的记录的 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]

此returns 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 应该是什么。

我还用谷歌搜索了 "Angular Firebase CRUD SHOW page",但 none 的示例 CRUD 应用程序有 SHOW 页面。我误解了一些基本的东西吗?例如,我是否应该在 INDEX 页面上使用 <ng-hide><ng-show> 构建 SHOW 和 EDIT 视图,而不必费心制作单独的 SHOW 和 EDIT 页面?

您遇到的问题是异步数据流。

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 抓取单个项目,而不是下载整个列表并提取一个项目。

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

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>