提问人:mikegertrudes 提问时间:7/25/2015 最后编辑:mikegertrudes 更新时间:7/27/2015 访问量:882
在服务器端渲染初始 Angular ng-view 并从那里获取它
Render initial Angular ng-view on server-side and take it from there
问:
我想避免显示初始 JavaScript 呈现视图的延迟。我希望用户立即看到内容并让 Angular 从那里获取它。我不想在 Angular ngRoute 启动时替换这个 ng-view,因为可能会发生眨眼。我只希望它在用户到达另一条路线时替换它。
让我们想象一下这是基本路线。这已经存在于我的 HTML 中,从服务器呈现。'/'
<div ng-view>
<h1>Welcome. I am the first view.</h1>
<p>Please do not replace me until a user has triggered another route.</p>
</div>
我知道一种常见的方法是在 an 中加入一些服务器端代码,当 Angular 加载时,它只是替换它。这不是我想要做的。我希望 Angular 加载并理解这实际上已经是我的第一个视图。ng-view
关于如何做到这一点,有什么创意吗?我看过源代码 - 没有运气。也许甚至有一种让 Angular 只替换 HTML 的方法,如果它不同。
编辑:
我不想在服务器端渲染模板以用作 Angular 模板。我希望在服务器端渲染我的整个过程,并且已经包含用户需要看到的初始基本路由的所有内容。index.html
答:
ngCloak
ngCloak 指令用于防止浏览器在加载应用程序时以原始(未编译)形式短暂显示 Angular html 模板。使用此指令可避免 html 模板显示导致的不良闪烁效果。
https://docs.angularjs.org/api/ng/directive/ngCloak
<body ng-cloak>
您应该阅读这篇文章 http://sc5.io/posts/how-to-implement-loaders-for-an-angularjs-app
评论
ng-cloak
在任何手机上 6-10 秒都是非常糟糕的。我不会在这里责怪 angular,angular 只有 30kb,如果仍然太慢,那么你选择了错误的任务框架。
使用分析工具了解正在发生的事情。
- 您正在处理的应用程序有多大?
- 您可以将应用程序拆分为子应用程序吗?
- 你已经在为CSS和JS做缩小了吗?
- 您是否懒惰地加载所有视图和控制器?
- 你在压缩一切吗?(gzip)
无论如何,可以在服务器端为您的index.html进行预处理
例如,您可以使用 nodejs 进行预处理,并缓存预处理index.html。
你的 nodejs 预处理器可以做(伪代码):
function preprocessIndexHtml(queryString) {
if(cached[queryString])) return cached[queryString];
// assume angular.js is loaded
// routeConfiguration is an object that holds controller & url.
var routeConfiguration = $routeProvider.
figureOutRouteConfigurationFor(queryString);
var domTree = $(file('index.html'));
var $rootScope = $injector.get('$rootScope');
// find ng-view and clone it
var yourNgView = $($("attribute[ng-view='']").outerHTML);
// le's get rid of existing ng-view attribute
// and configure new ng-view with templateUrl & controller.
yourNgView.RemoveNgViewAttribute();
yourNgView.AddAttribute("ng-controller", routeConfiguration.controller);
yourNgView.AddAttribute("ng-view", routeConfiguration.templateUrl);
// compile the view & pass the rootScope.
$compile(yourNgView)($rootScope);
// replace the existing dom element with our compiled variant
$("attribute[ng-view='']").replaceHtmlWith(yourNgView);
// we can now cache the resulted html.
return cached[queryString] = domTree.html;
}
评论
run