正如标题所暗示的那样,我试图通过http get请求从数据库中获取一些数据,然后使用ngRepeat将其显示在div列表中。我需要在每个重复的ngRepeat项上调用一个函数,以便请求可以使用该对象(“房间中的房间”中的“房间”)作为url参数。我认为这个问题是因为我已经隔离了函数的范围,所以来自http请求(计数)的响应似乎超出了函数的范围。我怎样才能这样做,以便我可以在视图{{count}}中显示响应,同时将其保留在自己的隔离范围内,具有该功能?
HTTP
<div ng-repeat="room in rooms">
<div>{{room}}</div><br>
<div plant attrcount="plantCount(room)"></div>
</div>
server.js
MongoClient.connect(process.env.MONGOLAB_URI, function(err, db) {
var plantList = db.collection("plantList");
app.get('/getrooms', function(req, res) {
plantList
.distinct("room", function(err, docs) {
res.json(docs);
});
});
app.get('/getplantsbyroom/:room', function(req, res) {
var roomReq = req.params.room;
plantList.count({"room":roomReq}, function(err, count) {
res.json(count);
});
});
});
controller.js
angular.module('myApp').controller('AppCtrl', function($scope, $http) {
$http.get('/getrooms').success(function (response) {
$scope.rooms = response;
});
$scope.plantCount = function(room) {
var url = '/getplantsbyroom/' + room;
$http.get(url).success(function (response) {
$scope.count = response;
})
}
});
angular.module('myApp').directive("plant", function() {
return {
scope: {
attrcount:"&"
},
template: '<p ng-init="attrcount(room)">{{count}}</p>' //doesn't display count
}
});
答案 0 :(得分:1)
最好先将所有数据放在一起,然后再在控制器中使用它,而不是尝试将其加载到ng-reapeat中。 Angular的$q服务可以帮助您与$q.all一起加入多个promisses。为了保持清洁,您可以创建自己的服务来管理您的请求,并将其注入您的控制器。
controller('AppCtrl', function($scope, RoomService) {
RoomService.listRooms().then(function(rooms) {
$scope.rooms = rooms;
});
}).service("RoomService", function($http, $q) {
var roomService = {};
roomService.listRooms = function() {
return $http.get("rooms").then(function(rooms) {
return $q.all(rooms.map(roomService.getPlantCount));
});
}
roomService.getPlantCount = function(room) {
return $http.get('/getplantsbyroom/' + room).then(function(plantCount) {
return {
room: room,
plantCount: plantCount
};
});
}
return roomService;
})
angular.module('myApp', []).
controller('AppCtrl', function($scope, RoomService) {
RoomService.listRooms().then(function(rooms) {
$scope.rooms = rooms;
});
}).service("RoomService", function($httpMock, $q) {
var roomService = {};
roomService.listRooms = function() {
return $httpMock.get("rooms").then(function(rooms) {
return $q.all(rooms.map(roomService.getPlantCount));
});
}
roomService.getPlantCount = function(room) {
return $httpMock.get('/getplantsbyroom/' + room).then(function(plantCount) {
return {
room: room,
plantCount: plantCount
};
});
}
return roomService;
}).service("$httpMock", function($q) {
var $httpMock = {};
$httpMock.get = function(url) {
return (url === "rooms") ?
$httpMock.mockRooms() : $httpMock.mockPlantCount(url);
}
$httpMock.mockRooms = function() {
var deferred = $q.defer();
deferred.resolve(["lorem", "ipsum"]);
return deferred.promise;
}
$httpMock.mockPlantCount = function(url) {
var deferred = $q.defer();
if (url === "/getplantsbyroom/lorem") {
deferred.resolve(3);
} else {
deferred.resolve(15);
}
return deferred.promise;
}
return $httpMock;
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="AppCtrl">
<div ng-repeat="room in rooms">
<div>{{room.room}}</div>
<br>
<div>{{room.plantCount}}</div>
</div>
</div>
&#13;
答案 1 :(得分:0)
我想到了几件事情,
1. $scope.plantCount
函数应返回计数。
$scope.plantCount = function(room) {
var url = '/getplantsbyroom/' + room;
$http.get(url).success(function (response) {
$scope.count = response;
return response
})
}
});
2。而不是通过函数返回从父访问值调用函数,因为您已经在父属性中调用它。 了解指令范围在tickets
中的工作原理这是我尝试过的解决方案及其工作方式,我用默认值替换了方法。
angular.module('app', [])
.controller('AppCtrl', function($scope, $http) {
$scope.rooms = [{
Name: "room1",
PlantsCount: "1"
},
{
Name: "room2",
PlantsCount: "2"
}];
$scope.plantCount = function(room) {
return room.PlantsCount;
}
})
.directive("plant", function() {
return {
scope: {
attrcount: "="
},
template: '<p >{{attrcount}}</p>' //doesn't display count
}
});
可以像,
一样使用 <body ng-app="app" ng-controller="AppCtrl">
<div ng-repeat="room in rooms">
<div>{{room.Name}}</div>
<br>
<div plant attrcount="plantCount(room)"></div>
</div>
</body>