要学习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>
这没什么区别。
我尝试使用
解析网址中的IDvar 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页面吗?
答案 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>