2014-09-09 2 views
0

Как синхронно самонастройки в angularjs приложенияКак синхронно самонастройки в angularjs приложения

я определяю пару постоянных значений на моем объекте приложения. Некоторые из этих значений необходимо установить с помощью вызова службы, и эти вызовы должны быть выполнены до того, как будет создан экземпляр любого из моих контроллеров.

В приведенном ниже примере я определяю массив значений для объекта с именем config. Мне нужно установить значение с именем PostIndexMenuID до того, как будет создан экземпляр любого из моих контроллеров. Как мне это сделать?

Я пробовал вручную загрузку (удаление ng-app из html). Я не использую маршрутизацию.

В идеале мне не нужно будет изучать, скачивать, устанавливать, настраивать, тестировать и поддерживать другую инфраструктуру для достижения этой цели.

(function() 
{ 
    angular.module('app', []); 
    var app = angular.module('app'); 
    app.controller('controller', ['$scope', 'config', '$http', controller]); 
    app.service('menusService', ['$http', 'config', menusService]); 

    // Create config object. Some values are set in app.run 

    app.value('config', { 
     siteID:    100, 
     webRoot:   '', 
     apiRoot:   '/api', 
     imageRoot:   '/Content/images', 
     PostIndexMenuID: 0 
    }); 


    app.run(['$http', 'config','menusService', function ($http, config, menusService) { 

     menusService.GetMenuIDByName("PostIndex", function (data) { 
      config.PostIndexMenuID = data; // Need to complete this BEFORE GetPosts on the controller is called 
     }); 

    }]); 

    function controller($scope, config, $http) { 
     var vm = this; 
     vm.Posts = 0; 

     function GetPosts() { 
      // In prod we call a service here get posts based on config.PostIndexMenuID 
      // for this example just return PostIndexMenuID. 

      vm.Posts = config.PostIndexMenuID; 
     }; 

     GetPosts(); // need to delay calling this until AFTER PostIndexMenuID is set 
    }; 

    function menusService($http, config) { 
     this.GetMenuIDByName = function (menuName, callBack) { 
      var uri = config.apiRoot + '/menu/GetMenuByName?menuName=' + menuName + '&siteID=' + config.siteID; 

      // use a timeout to simulate a slow service for this example and return a dummy value 
      var menuID = 99; 
      setTimeout(function() { 
       callBack(menuID); 
      }, 2000); 

     }; 
    }; 

})() 

// HTML

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="app" > 
<head> 
    <title></title> 
</head> 
<body > 
    <div ng-controller = "controller as vm"> 
     <p>PostIndexMenuId is {{ vm.Posts }}</p> 
    </div> 
    <script src="Scripts/jquery-1.8.2.js"></script> 
    <script src="Scripts/angular.js"></script> 
    <script src="Scripts/angular-route.js"></script> 
    <script src="app/app.js"></script> 
</body> 
</html> 

ответ

0

Существует довольно изящный трюк в Angular.js, в котором вы можете отложить изменение маршрута, пока все обещания не были решены. Возможно, вам придется немного изменить структуру приложения, чтобы удовлетворить этот подход, но я использую его сам, и он работает как удовольствие!

$rootScope.$on('$routeChangeStart', function $routeChangeStart(event, next) { 

    // Extend the resolution of the route promise to wait for the user authentication 
    // process to determine if there's a valid session available. 
    next.resolve = angular.extend(next.resolve || {}, { 
     authenticating: api.isSession 
    }); 

}); 

С помощью next.resolve вы расширяете последовательность угловых по обещаниям, которые решены до того, как изменение маршрута считается успешным. В приведенном выше случае, если api.isSession возвращает обещание, тогда все будет работать чудесно.

Как только обещание api.isSession было разрешено, изменение маршрута будет успешным, и в вашем случае ваш контроллер будет загружен.

+0

Благодарим вас за это - где я могу поместить этот код? – Sam

+0

Внутри вашего 'app.run'. – Wildhoney

+0

routeChangeStart никогда не вызывается. Я загружаю angular-route.js, модифицированный app.run для ввода $ rootScope. next.resolve никогда не присваивается значение. – Sam

Смежные вопросы