我有以下简单的基本指令:
angular.module("base", [])
.directive("base", function() {
return {
restrict: "A",
scope: true,
controller: function($scope) {
this.setHeader = function(header) {
$scope.header = header;
}
this.setBody = function(body) {
$scope.body = body;
}
this.setFooter = function(footer) {
$scope.footer = footer;
}
},
templateUrl: "base.html"
}
});
我通过以下方式将数据传递给该指令:
.directive("custom", function() {
return {
restrict: "E",
require: "^base",
scope: {
ngModel: "="
},
link: function($scope, $element, $attrs, baseCtrl) {
//Do something with the data or not...
baseCtrl.setHeader($scope.ngModel.header);
baseCtrl.setBody($scope.ngModel.body);
baseCtrl.setFooter($scope.ngModel.footer);
}
}
});
当我创建 custom
指令列表时,我注意到 custom
指令不会立即呈现。我做了一个Plunker demonstrating这种行为。 (您将看到列表单元格瞬间为空,然后指令将出现)
此设计背后的目标是重用 base
指令的模板,并仅传递显示所需的数据。在这个简单的示例中, $scope.data
正是我需要传入的内容,但可能需要先发生一些规则或操作。我不想让查询数据的 Controller 处理这个问题,而是想将其传递到指令中,从而分离关注点。
所以我的问题是:
- 有什么方法可以使指令渲染速度更快并避免 Plunker 中显示的闪烁吗? ?
- 这是在 Angular 中重用指令的最佳实践吗?
最佳答案
闪烁是由对 "base.html"
文件的异步 http 请求引起的。由于 base
指令的 HTML 必须从服务器加载,因此在一小部分时间内不会显示任何内容。
为了渲染数据
,Angular 将经历以下 3 个阶段:
- 从服务器获取 HTML 文件/模板(不会显示任何内容)
- 编译 HTML 模板(DOM 已更新,但范围尚未链接)
- 将范围链接到 DOM/模板(显示预期数据)
选项 1 - 使用template
属性
只需将 templateUrl: "base.html"
替换为直接 HTML 内容即可:
//templateUrl: "base.html"
template: '<div class="base"><div class="header bottom-border"><h2>{{header}}</h2><div><div class="body bottom-border"><p>{{body}}</p></div><div class="footer">{{footer}}</div></div>',
您会注意到这次不会有任何闪烁(检查此 plunker )。
选项 2 - 预加载模板文件
Angular 有一个内置模板缓存 ( $templateCache
),用于检查是否已从服务器获取任何 HTML 模板文件/内容。如果您在应用程序加载时填充该缓存,那么 Angular 将不需要获取模板来渲染指令,它将直接从缓存中读取它。
您可以使用 Angular 的 $templateRequest
(如果您使用的是 Angular 的最新测试版)或 $templateCache
(对于任何版本)。
不同之处在于 $templateRequest
自动发出 HTTP GET 请求并将结果存储在 $templateCache
中。另一方面,您必须手动执行此操作,如下所示:
loadTemplate = function(tpl) {
$http.get(tpl, { cache : $templateCache })
.then(function(response) {
$templateCache.put(tpl, html);
return html;
});
};
loadTemplate('base.html');
但请注意,此方法需要您的应用程序有一个“加载阶段”。
关于重用指令的最佳实践,您似乎走在正确的道路上。这个例子太简单了,无法提供任何建议......不过,请检查此 Angular "Creating Custom Directives" 中的“最佳实践”注释指南。
编辑
(我的个人关于模板
的偏好与templateUrl
)
如果主要目标仅仅是性能(即页面渲染速度),那么模板
似乎是最佳选择。获取一个文件总是比获取两个文件更快...但是,随着应用程序的增长,必须需要良好的结构,而模板文件是最佳实践之一。
通常我遵循这个“规则”:
- 如果模板中只有几行 HTML,则只需使用
template
- 如果 HTML 模板不会随时间不断变化(即帖子结构、联系方式等),请使用
template
,否则(即包含横幅/广告的模板)请使用模板网址
- 如果应用有加载阶段,请使用带有缓存的
templateUrl
关于javascript - 在 AngularJS 中重新执行指令时出现渲染速度问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25587704/