Angular Firebase(AngularFire)CRUD SHOW和EDIT页面?

时间:2015-12-13 23:04:30

标签: javascript angularjs firebase crud angularfire

要学习AngularFire,我试图构建一个简单的CRUD应用程序。 INDEX和NEW页面顺利进行,但我仍然停留在SHOW和EDIT页面上。我无法在SHOW页面上显示所选记录。

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

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

这会将记录ID放入网址,例如www.website.com/#/K9hr32rhror

然后在SHOW页面上,您可以使用{{record.title}}{{record.author}}或任何您想要的内容。 Angular会神奇地记住您在INDEX页面上单击的记录的ID。我不知道这是多么角色。 : - )

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

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

这会成功将ID放入网址。

问题是SHOW页面上没有显示任何记录。 Angular似乎忘记了{{record}}所指的内容。

我尝试过引导/

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

这没什么区别。

我尝试使用

解析网址中的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搜索&#34; Angular Firebase CRUD SHOW页面&#34;但是没有一个示例CRUD应用程序有SHOW页面。我误解了一些基本的东西吗?例如,我应该在INDEX页面上使用<ng-hide><ng-show>构建SHOW和EDIT视图,而不打算单独制作SHOW和EDIT页面吗?

2 个答案:

答案 0 :(得分: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 :(得分: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>