在整页加载Angular之前添加“中间”页面

时间:2013-11-13 06:32:14

标签: angularjs angularjs-routing

我的问题

我正在使用Angular创建一个Phonegap应用程序。我的大多数页面都相当小,转换/响应速度快速而顺畅。但是,我有一个相当大的页面,我遇到了问题。

更改为此页面的方法很简单:

<button ng-click="$location.url('/page2')"></button>

当您“点击”上面的按钮时,大约需要1-2秒来响应并更改页面。我在本页面上仔细检查了所有需要改进的地方,并确定延迟是由更改页面之前Angular编译和解析此页面的DOM引起的。请注意,我在真实设备上进行测试,因此不是因为模拟器的速度。

问题

是否有办法自动或手动拦截页面更改并将其置于某种“加载”页面中,以便立即响应按钮单击并且页面更改可见,但页面内容在一秒或两秒后加载到这个“加载”页面。

它只是一个问题,因为点击某些内容并且没有任何结果是非常尴尬的。我很难在这个问题上找到任何资源,所以如果有人能指出我正确的方向看我会很感激。

修改

我发现一个超级hacky解决方案是在包装页面上使用ng-include并稍微延迟包含。

myBigPageWrapper.html:

<div ng-include="page"></div>

控制器:

$scope.page = '';
setTimeout(function() { $scope.page='/pages/myBigPage.html'; $scope.$apply(); }, 1000);

然后导航到您的包装页面:$ location.url('/ myBigPageWrapper')

这显然不太理想......但我希望这有助于澄清我想要做的事情。

Page2.html

这是导致页面速度变慢的部分,对此进行注释会使页面加载速度非常快。 “auditPages”数组中有13个页面,每个页面包含大约50行html,主要包含表单输入元素。相当多的逻辑,但一旦加载它运行良好。我不打算包含所有页面,因为它会超载。

<div class="page-contents">
    <form name="auditPageForm">
        <div ng-repeat="(pageKey, pageData) in auditPages " ng-show="currentAuditPage.name==pageData.name">
            <audit-form page="pageData">
                <ng-include src=" 'partials/audit/auditSections/'+pageData.name+'.html'" onload="isFormValid(pageKey)"></ng-include>
            </audit-form>
        </div>
    </form>
</div>

2 个答案:

答案 0 :(得分:1)

Angular有 $ httpProvider.responseInterceptors

// zdam的原文:http://jsfiddle.net/zdam/dBR2r/

angular.module('LoadingService', [])
.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.responseInterceptors.push('myHttpInterceptor');
    var spinnerFunction = function (data, headersGetter) {
        angular.element(document.getElementById('waiting')).css('display','block');
        return data;
    };
    $httpProvider.defaults.transformRequest.push(spinnerFunction);
}])
// register the interceptor as a service, intercepts ALL angular ajax http calls
.factory('myHttpInterceptor', ['$q','$window', function ($q, $window) {
    return function (promise) {
        return promise.then(function (response) {
            angular.element(document.getElementById('waiting')).css('display','none');
            return response;

        }, function (response) {
            angular.element(document.getElementById('waiting')).css('display','none');
            return $q.reject(response);
        });
    };
}])

答案 1 :(得分:1)

总结我的评论:

你的问题是:

  

有没有办法自动或手动拦截页面更改和   把它们放在一个“加载”页面?

很多人都会问这个问题,因为Angular似乎没有很好地处理加载过渡。

事实上,可能最好的解决方案是使用angular的模块配置的resolve属性“播放”。
众所周知,resolve允许在呈现目标页面之前运行一些逻辑,处理承诺。理想的情况是能够在resolve代码运行时将加载页面放在此目标页面上。

所以有些人有像这样的好主意: Nice way to handle loading icon while route is changing 他使用$routeChangeStart事件,因此加载图标将在SOURCE页面上发生 我使用它并且效果很好。

此外,还有另一种方法:使用$http拦截器(如上面的@oori回答),有一个公共代码允许放置加载图标但是......我想你不想要在页面上的每种http请求上都有相同的图标,这取决于你。

也许在未来,解决方案将直接与resolve属性相关联。