2015-03-31 3 views
1

Я пишу приложение AngularJS, и я пытаюсь добиться определенных целей, но поскольку я очень новичок в Angular, я хочу получить мнение некоторых экспертов AngularJS.Как дождаться загрузки ресурсов

Я создаю набор управления на самом деле в AngularJS и состоит из 2-х частей, экрана загрузки и экрана отображения, оба из которых определены в HTML.

Данные, которые мне нужно манипулировать, хранятся в файлах JSon. Чтобы дать вам идею, вот первая JSon файл:

{ 
    "Styles": [ 
    { "name": "Blue", "stylesheet": "/Resources/Stylesheets/Styles/Blue/OfficeUI.Style.Blue.min.css" }, 
    { "name": "Green", "stylesheet": "/Resources/Stylesheets/Styles/Green/OfficeUI.Style.Green.min.css" }, 
    { "name": "LightBlue", "stylesheet": "/Resources/Stylesheets/Styles/LightBlue/OfficeUI.Style.LightBlue.min.css" }, 
    { "name": "Orange", "stylesheet": "/Resources/Stylesheets/Styles/Orange/OfficeUI.Style.Orange.min.css" }, 
    { "name": "Purple", "stylesheet": "/Resources/Stylesheets/Styles/Purple/OfficeUI.Style.Purple.min.css" }, 
    { "name": "Red", "stylesheet": "/Resources/Stylesheets/Styles/Red/OfficeUI.Style.Red.min.css" }, 
    { "name": "Turquoise", "stylesheet": "/Resources/Stylesheets/Styles/Turquoise/OfficeUI.Style.Turquoise.min.css" } 
    ], 
    "DefaultStyle": "LightBlue", 

    "Themes": [ 
    { "name": "No Background", "stylesheet": "/Resources/Stylesheets/Themes/No Background/OfficeUI.Themes.No-Background.min.css" }, 
    { "name": "Calligraphy", "stylesheet": "/Resources/Stylesheets/Themes/Calligraphy/OfficeUI.Themes.Calligraphy.min.css" }, 
    { "name": "Circles And Stripes", "stylesheet": "/Resources/Stylesheets/Themes/Circles-And-Stripes/OfficeUI.Themes.Circles-And-Stripes.min.css" }, 
    { "name": "Circuit", "stylesheet": "/Resources/Stylesheets/Themes/Circuit/OfficeUI.Themes.Circuit.min.css" }, 
    { "name": "Clouds", "stylesheet": "/Resources/Stylesheets/Themes/Clouds/OfficeUI.Themes.Clouds.min.css" }, 
    { "name": "Doodle Circles", "stylesheet": "/Resources/Stylesheets/Themes/Doodle-Circles/OfficeUI.Themes.Doodle-Circles.min.css" }, 
    { "name": "Doodle Diamonds", "stylesheet": "/Resources/Stylesheets/Themes/Doodle-Diamonds/OfficeUI.Themes.Doodle-Diamonds.min.css" }, 
    { "name": "Geometry", "stylesheet": "/Resources/Stylesheets/Themes/Geometry/OfficeUI.Themes.Geometry.min.css" }, 
    { "name": "Lunchbox", "stylesheet": "/Resources/Stylesheets/Themes/Lunchbox/OfficeUI.Themes.Lunchbox.min.css" }, 
    { "name": "School Supplies", "stylesheet": "/Resources/Stylesheets/Themes/School-Supplies/OfficeUI.Themes.School-Supplies.min.css" }, 
    { "name": "Spring", "stylesheet": "/Resources/Stylesheets/Themes/Spring/OfficeUI.Themes.Spring.min.css" }, 
    { "name": "Stars", "stylesheet": "/Resources/Stylesheets/Themes/Stars/OfficeUI.Themes.Stars.min.css" }, 
    { "name": "Straws", "stylesheet": "/Resources/Stylesheets/Themes/Straws/OfficeUI.Themes.Straws.min.css" }, 
    { "name": "Tree Rings", "stylesheet": "/Resources/Stylesheets/Themes/Tree-Rings/OfficeUI.Themes.Tree-Rings.min.css" }, 
    { "name": "Underwater", "stylesheet": "/Resources/Stylesheets/Themes/Underwater/OfficeUI.Themes.Underwater.min.css" } 
    ], 
    "DefaultTheme": "Geometry", 
    "Configuration": "/Resources/Data/Application.json", 
    "Controls": [ 
    { "Name": "Ribbon", "ConfigurationFile": "/Configuration/Application/OfficeUI.Ribbon.config.json" } 
    ] 
} 

Как вы видите, файл не содержит некоторые ссылки на таблицы стилей, которая должна быть встроена в страницу dynamiccaly.

Теперь перейдем к части AngularJS.

Прежде всего, у меня есть определение моего модуля:

var OfficeUI = angular.module('OfficeUIApplication', ['ngSanitize']); 

Тогда у меня есть сервис, который загружает файл в формате JSON, определенное выше:

OfficeUI.factory('OfficeUIConfigurationService', function($http) { 
    // Defines the object that this service needs to return. 
    return { 
     getOfficeUIConfiguration: function() { 
      // Check if the location of the file can be found somewhere. If it cannot be found, throw an error. 
      if (typeof $.fn.OfficeUI.Settings.OfficeUIConfigurationFileLocation === 'undefined' || $.fn.OfficeUI.Settings.OfficeUIConfigurationFileLocation == '') { 
       OfficeUICore.Exceptions.officeUIConfigurationException('The OfficeUI Configuration file is not defined.'); 
      } 

      // Returns the 'httpPromise' which is required for further processing. 
      return $http.get($.fn.OfficeUI.Settings.OfficeUIConfigurationFileLocation) 
       .then(function (response) { 
        return { 
         Styles: response.data.Styles, 
         DefaultStyle: response.data.DefaultStyle, 
         Themes: response.data.Themes, 
         DefaultTheme: response.data.DefaultTheme, 
         Configuration: response.data.Configuration, 
         Controls: response.data.Controls 
        }; 
       }, function(error) { OfficeUICore.Exceptions.officeUILoadingException('The OfficeUI Configuration file: \'' + $.fn.OfficeUI.Settings.OfficeUIConfigurationFileLocation + '\' could not be loaded.'); } 
      ); 
     } 
    } 
}); 

Тогда я имея мой контроллер:

OfficeUI.controller('OfficeUIController', function(OfficeUIConfigurationService, $scope, $http) { 
    $scope.isInitialized = false;   // Indicates that the entire OfficeUI application has been loaded. 
    $scope.loadingScreenLoaded = false;  // Indicates that the data for the loading screen has been loaded. 

    // Initialize all the required components for the website. 
    Initialize(); 

    function Initialize() { 
     OfficeUIConfigurationService.getOfficeUIConfiguration().then(function(data) { 
      var foundStyles = JSPath.apply('.{.name == "' + data.DefaultStyle + '"}', data.Styles); 
      var foundThemes = JSPath.apply('.{.name == "' + data.DefaultTheme + '"}', data.Themes); 

      $scope.Style = foundStyles[0].stylesheet; 
      $scope.Theme = foundThemes[0].stylesheet; 

      // Set a value that indicates that the loading screen has been loaded. So, at this point, the loading screen 
      // can be rendered. 
      $scope.loadingScreenLoaded = true; 

      // Returns the 'httpPromise' which is required for further processing. 
      $http.get(data.Configuration) 
       .then(function (response) { 
         $scope.Title = response.data.Title; 
         $scope.Icons = response.data.Icons; 
       }, function(error) { OfficeUICore.Exceptions.officeUILoadingException('The OfficeUI application definition file: \'' + data.Configuration + '\' could not be loaded.'); } 
      ); 
     }); 

     setTimeout(function() { 
      $scope.isInitialized = true; 
      $scope.$apply(); 
     }, 2000); 
    } 
}); 

Примечание: Я установил Тимео здесь, чтобы убедиться, что экран загрузки отображается в течение 2 секунд.

В этом контроллере, вы найдете следующий фрагмент кода:

OfficeUIConfigurationService.getOfficeUIConfiguration().then(function(data) { 
    var foundStyles = JSPath.apply('.{.name == "' + data.DefaultStyle + '"}', data.Styles); 
    var foundThemes = JSPath.apply('.{.name == "' + data.DefaultTheme + '"}', data.Themes); 
    $scope.Style = foundStyles[0].stylesheet; 
    $scope.Theme = foundThemes[0].stylesheet; 
    // Set a value that indicates that the loading screen has been loaded. So, at this point, the loading screen 
    // can be rendered. 
    $scope.loadingScreenLoaded = true; 
    // Returns the 'httpPromise' which is required for further processing. 
    $http.get(data.Configuration) 
     .then(function (response) { 
       $scope.Title = response.data.Title; 
       $scope.Icons = response.data.Icons; 
     }, function(error) { OfficeUICore.Exceptions.officeUILoadingException('The OfficeUI application definition file: \'' + data.Configuration + '\' could not be loaded.'); } 
    ); 
}); 

Что это делает, с моей загрузкой службы, извлекать и анализировать файл JSON, и на основе значений в этом файле, назначьте значение Style и Theme, которые оба являются областями объектов.

В моем HTML, это визуализируется как это (в головной части файла):

<link rel="stylesheet" href="#" data-ng-href="{{Style}}" /> 
<link rel="stylesheet" href="#" data-ng-href="{{Theme}}" /> 

Это позволяет мне изменить внешний вид моего приложения dynamiccaly (путем вызова метода, который изменить значение области).

Однако может возникнуть проблеска. Когда файл Json загружен и разобран, я присвоить значение loadingScreenLoaded, который убеждается, что экран загрузки в настоящее время показало:

<div class="loading-area center-screen no-select" data-ng-if="loadingScreenLoaded && !isInitialized"> 

Однако в данном конкретном случае, это может быть, что файл CSS по-прежнему загружается ,

Так что вопрос не в том, как не показывать загрузку DIV на странице, пока были загружены все ресурсы (CSS, ...)

Также, если возможно, есть способ сделать то же самое с директивой ng-include, изображениями, ...

С наилучшими пожеланиями,

ответ

0

Это не рекомендуется использовать тайм-аут, я не могу ожидать, что ваши ресурсы будут готовы после 2000

setTimeout(function() { 
     $scope.isInitialized = true; 
     $scope.$apply(); 
    }, 2000); 

Я рекомендую вам использовать файл и модуль библиотеки загрузчика. Попробуйте использовать угловой с requirejs

Смотрите этот пример использования angularjs + requirejs

+0

На вопрос о том, что прямо сейчас, это только реализовано, чтобы убедиться, что экран загрузки отображается в течение 2 секунд (иначе он исчезнет почти сразу). И я не вижу, как requireJS может помочь мне в этой ситуации. Вопрос в том, как подождать, пока не будут готовы ресурсы, А.К. Предзагрузка. – Complexity

0

Tag имеет событие "OnLoad". Подробности here. Но вы должны проверить совместимость браузера, если он удовлетворяет всем браузерам, которые вам нужны.

<link rel="stylesheet" href="mystylesheet.css" onload="sheetLoaded()" onerror="sheetError()"> 

В другом случае вы можете рассмотреть динамические методы загрузки ресурсов. Например, this. Кроме того, вы можете использовать сторонние библиотеки, которые фактически реализуют динамическую загрузку ресурсов (angular-load или, как указано в @ran, requirejs).

Вопрос заключается в том, чтобы ждать, пока ресурсы не будут готовы

Вы можете прикрепить обработчик события «OnLoad» (или третьей стороной библиотеки конкретного события, это зависит от того, что Вы выбираете), который будет выполняться когда ваши ресурсы готовы.

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