-1

我的 Angular 应用程序有两个大问题,我完全陷入困境,希望有人能帮助我。

  1. 我将数据从 Web 服务共享到多个控制器的方法存在缺陷,我不知道如何修复它。
  2. 我的指令偶尔无法访问控制器范围内的数据(可能是因为问题 1)并且记录为未定义,我认为路由更改发生在范围数据被解析之前。

所以,详细信息,我有一个 Angular 应用程序,它提供了一个表格,人们可以在我们的网站上注册他们的酒店,人们可以保存他们的详细信息,稍后再回来编辑。

我的应用程序设置如下。

我有控制器和路由:

  • 酒店信息(名称、位置、费用等)
  • 房间
  • 设施(游泳池、桑拿、蒸汽浴室等)
  • 业主详细信息(姓名、电子邮件、银行详细信息)
  • 可用性
  • 相片

我有一个名为“HotelService”的工厂,它调用网络服务来检索/存储有关酒店的数据。

我想在控制器之间共享数据,所以我一直将在网络服务上检索到的数据存储在 $rootScope 中,我看到人们通常不认为这是“有角度的方式”,但我没有无法找到任何其他方法来实现相同的目标。这也使得使用这种技术测试我的控制器变得困难。所以我对另一种解决方案持开放态度。

重要的部分是我不想向 Web 服务发出多个初始“GET”请求。获得数据后,我希望我的所有控制器都能够访问/更新该数据,用户可以随时从任何控制器保存所有数据。

一些代码:

这是我的应用程序配置:

app.config(['$routeProvider', function($routeProvider)
{
  $routeProvider
    .when('/', {
      templateUrl: '/views/info.html',
      controller:  'InfoController'
    })
    .when('/rooms', {
      templateUrl: '/views/rooms.html',
      controller:  'RoomsController'
    })
    .when('/facilities', {
      templateUrl: '/views/facilities.html',
      controller:  'FacilitiesController'
    })
    .when('/proprietor', {
      templateUrl: '/views/proprietor.html',
      controller:  'ProprietorController'
    })
    .when('/available', {
      templateUrl: '/views/available.html',
      controller:  'AvailableController'
    })
    .when('/photos', {
      templateUrl: '/views/photos.html',
      controller:  'PhotosController'
    });
}]);

这是我在 $rootScope 上设置数据的 app.run:

app.run(
['$rootScope', '$window', 'HotelService',
function($rootScope, $window, HotelService)
{
    HotelService.get($window.hotelId).then(function(hotel) {
        $rootScope.data = hotel;
    });
  }
]);

这是我的 HotelService 代码:

app.factory('HotelService', ['$http', '$rootScope', function ($http, $rootScope) {
  var hotel = {};
  return {
    get: function(hotelId) {
      premId = (angular.isUndefined(hotelId)) ? 0 : premId;
      return $http.jsonp('/webservice', {
        method: 'GET',
        params: { 'id': hotelId, 'callback': 'JSON_CALLBACK' },
        responseType: 'json'
        })
        .then(function(response) {
            hotel = response.hotel;
            $rootScope.$broadcast('handleSharedHotel', hotel);
            return hotel;
      });
    },
    save: function(data) {
      $rootScope.$broadcast('handleBeforeSaveHotel');
      return $http.jsonp('/webservice?callback=JSON_CALLBACK', {
        method: 'POST',
        data: data,
        responseType: 'json'
      }).then(function(response) {
        hotel = response.data.hotel;
        $rootScope.$broadcast('handleSharedHotel', hotel);
        $rootScope.$broadcast('handleAfterSaveHotel', response);
        return hotel;
      });
    }
  };
}]);

这是我的酒店信息控制器:

controllers.InfoController = [
  '$scope', '$window', '$rootScope', '$timeout', 'HotelService',
  function($scope, $window, $rootScope, $timeout, HotelService)
  {
    $scope.data = $rootScope.data;

    this.save = function() {
        HotelService.save($scope.data);
    };

    $scope.$on('handleSharedHotel', function(events, hotel) {
        $scope.data = hotel;
    });

    return $scope.InfoController = this;
}

];

我遇到的一个非常奇怪(奇怪,因为我还没有完全理解 Angular 中的作用域)的问题是,当路由发生变化时,我的指令没有及时获取数据,因此作用域值返回未定义。仅当我直接从地址栏或链接加载页面时才会发生这种情况,但似乎每次刷新页面时都会发生。

任何想法将不胜感激。

4

1 回答 1

0

我建议将返回的 Promise 缓存在里面HotelService,然后在需要返回数据的每个控制器中注入服务。

这意味着只有在您的一个控制器中调用这部分代码时才会第一次发出请求:

HotelService.get($window.hotelId).then(function(hotel) {
        $rootScope.data = hotel;
});

在所有后续调用中,hotelId将返回缓存的传入承诺。

[编辑]

有一个使用缓存实现的简化示例(只是get方法)HotelService(尽管我还没有测试过)。您将不得不对您的代码库进行一些更改,但想法就在那里:

app.factory('HotelService', ['$http', function ($http) {
    var service = {};

    var hotelPromisesCache = {};

    service.get = function (hotelId) {
        var hotelPromise = hotelPromisesCache[hotelId];

        if (hotelPromise == undefined) {
            hotelPromise = $http.jsonp('/webservice', {
                method: 'GET',
                params: { 'id': hotelId, 'callback': 'JSON_CALLBACK' },
                responseType: 'json'
            });

            hotelPromisesCache[hotelId] = hotelPromise;
        }

        return hotelPromise;
    };

    return service;
}]);

在酒店数据更改后不要忘记从缓存中删除承诺,否则您将返回缓存,而不是修改后的版本。

于 2013-09-03T12:18:24.907 回答