【问题标题】:Binding http GET response with isolate scopes in ngRepeat在 ngRepeat 中将 http GET 响应与隔离范围绑定
【发布时间】:2016-02-16 00:14:22
【问题描述】:

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

【问题讨论】:

  • 为什么要操心这个指令呢?
  • 您是否通过 $http 请求获得房间?类似$scope.rooms = $http.get()?
  • 因为每次调用 plantCount() 函数时,我都会将重复项的所有计数变量更改为相同的值。所以我需要隔离它们,这样每个重复的项目都是独一无二的。查看我的 node/express 代码可能会有所帮助,因此我也会将其发布。
  • @Austin,是的,这是正确的。我刚刚包括了上面的那一点。很抱歉!

标签: javascript angularjs


【解决方案1】:

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

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>

【讨论】:

    【解决方案2】:

    我认为有几件事出了问题, 1.$scope.plantCountfunction 应该返回计数。

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

    2。而不是从父访问值调用函数,因为您已经在父属性中调用它。 看看指令作用域在blog中是如何工作的

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

    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>
    

    【讨论】:

      猜你喜欢
      • 2015-08-02
      • 2017-09-22
      • 2014-12-26
      • 1970-01-01
      • 1970-01-01
      • 2015-06-15
      • 2015-05-14
      • 2015-09-22
      • 2021-04-17
      相关资源
      最近更新 更多