将http GET响应与ngRepeat中的隔离范围绑定

时间:2016-02-16 00:14:22

标签: javascript angularjs

正如标题所暗示的那样,我试图通过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
    }
});

2 个答案:

答案 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;
})

&#13;
&#13;
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;
&#13;
&#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>