Javascript 是否可以创建一个充当单例的指令?
我们有一个指令作为我们大型单页应用程序的一部分。我们在页面的多个位置使用相同的指令,每次它的行为和外观都完全相同。我们看到的主要问题是这个指令有一个ng repeat,它创建了几百个DOM元素 是否可以创建一个充当单例的指令?即,每次使用指令或缓存DOM元素的创建以提高速度时,集合上只有一个手表,而不是一个手表。还是有更好的方法在同一页面中多次使用相同的DOM元素Javascript 是否可以创建一个充当单例的指令?,javascript,angularjs,Javascript,Angularjs,我们有一个指令作为我们大型单页应用程序的一部分。我们在页面的多个位置使用相同的指令,每次它的行为和外观都完全相同。我们看到的主要问题是这个指令有一个ng repeat,它创建了几百个DOM元素 是否可以创建一个充当单例的指令?即,每次使用指令或缓存DOM元素的创建以提高速度时,集合上只有一个手表,而不是一个手表。还是有更好的方法在同一页面中多次使用相同的DOM元素 我一直在考虑使用自定义ng repeat来缓存创建的html并重用它,这是最好的方法吗?如果您对ng repeat生成的手表数量有问
我一直在考虑使用自定义ng repeat来缓存创建的html并重用它,这是最好的方法吗?如果您对ng repeat生成的手表数量有问题,您应该使用(已在angular 1.3中本机实现)
如果渲染本身存在问题,也许你应该考虑替代渲染器,比如
角在“服务”组件中有一个单独的概念。你不可能在没有黑客的情况下做出单例指令,但你完全可以让服务做到这一点——因为它们已经做到了。我实现这一点的方法是让服务进行数据工作,并将其公开给指令。这些指令只是访问服务,因为服务已经是单例的,所以它们都将共享一个数据对象/集合/模型。当然,这是可能的。这是:app.directive('sample',函数($compile,$timeout){
var缓存;
返回{
作用域:{sampleData:'@',sampleArray:'='},
//绑定的简单计数器
控制器:功能($scope){
$scope.getSampleData=函数(){
log('getSampleData');
返回$scope.sampleData;
};
},
//嵌套指令没有开销
终端:是的,
模板:{{{n}}{{::getSampleData()}}嗨!{{::getSampleData()}},
编译:函数(元素){
//将其包装成单个元素可能会使您免于意外
var contents=angular.element(“”).append(element.contents());
元素。empty();
返回函数(范围、元素、属性、ctrl){
cached=cached | |$compile(内容)(范围);
//post link中没有可用的插值模板,因此
$timeout(函数(){
元素.append(cached.clone().contents());
});
};
}
};
});
对编译阶段没有控制权,但缓存的模板可以在可能的情况下提供给指令。
您也可以考虑使用缓存服务代替本地变量。
没有人能保证它不会引起问题。除非您已经遇到了性能问题并应用了其他优化技巧(我个人认为是),否则上述方法应该被视为过早优化的特例(这是致命的罪过)。它真的独立于父范围吗?
app.directive('sample', function ($compile, $timeout) {
var cached;
return {
scope: { sampleData: '@', sampleArray: '=' },
// simple counter for bindings
controller: function ($scope) {
$scope.getSampleData = function () {
console.log('getSampleData');
return $scope.sampleData;
};
},
// no overhead for nested directives
terminal: true,
template: '<div ng-repeat="n in sampleArray">{{n}} {{::getSampleData()}}</div>Hi! {{::getSampleData()}}',
compile: function (element) {
// keeping it wrapped into single element may save you from surprises
var contents = angular.element('<div>').append(element.contents());
element.empty();
return function (scope, element, attrs, ctrl) {
cached = cached || $compile(contents)(scope);
// there's no interpolated template available in post-link, so
$timeout(function () {
element.append(cached.clone().contents());
});
};
}
};
});