2015-03-31 110 views
1

我正在编写一个AngularJS应用程序,我试图实现某些事情,但由于我对Angular非常陌生,因此我想要获得一些AngularJS专家的意见。如何等待资源被加载

我在AngularJS中创建了一个控件套件,它由两部分组成,一个是用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); 
    } 
}); 

注:我设置Timeo酒店请在此处确认加载屏幕正在显示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文件,并根据此文件中的值,分配一个值为StyleTheme,它们都是范围对象。

在我的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秒(否则它几乎立即消失)。在这种情况下,我看不出有什么要求JS能够帮助我。问题是如何等待资源准备好,A.K.A.预加载。 – Complexity 2015-03-31 07:01:17

0

标签的活动“的onload”这个例子。详情here。但是,如果浏览器满足您需要的所有浏览器,则应该检查浏览器兼容性。

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

在其他情况下,您可以考虑动态资源加载技术。例如this。此外,您可以使用实际实现动态资源加载的第三方库(angular-load或者,如@ran说的requirejs)。

的问题是如何要等到资源准备

您可以将事件处理程序附加到“onload事件”(或第三方库特定的事件,这取决于你的选择)将被执行当你的资源准备好了。