将 http GET 响应与 ngRepeat 中的隔离作用域绑定

Binding http GET response with isolate scopes in ngRepeat

本文关键字:隔离 作用域 绑定 ngRepeat http GET 响应      更新时间:2023-09-26

正如标题所暗示的那样,我正在尝试通过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>

服务器.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);
        });
    });
});

控制器.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
    }
});

在控制器中使用之前,最好将所有数据放在一起,而不是尝试在ng-reapeat中加载它。Angular的$q服务可以帮助您将多个承诺与$ q.all.To 保持清洁,您可以创建自己的服务来管理您的请求,然后将其注入控制器。

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

我想到了几件事出错,1. $scope.plantCount函数应返回计数。

$scope.plantCount = function(room) {
        var url = '/getplantsbyroom/' + room;
        $http.get(url).success(function (response) {
            $scope.count = response;
            return response
        })
    }
});

2. 而不是从父访问值调用函数,因为您已经在父属性中调用它。在博客中查看指令范围的工作原理

这是我尝试的解决方案及其工作,我用默认值替换了方法。

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>