使用 nginclude 时避免使用额外的 DOM 节点
Posted
技术标签:
【中文标题】使用 nginclude 时避免使用额外的 DOM 节点【英文标题】:Avoid using extra DOM nodes when using nginclude 【发布时间】:2013-07-09 11:42:14 【问题描述】:我正在努力思考如何让 ng-include 不使用额外的 DOM 元素,因为我正在从纯 html 演示构建角度应用程序。我正在使用非常纤薄的 HTML 和完全开发的、紧密 DOM 耦合的 CSS(由 SASS 构建),并且我想不惜一切代价避免重构。
这是实际代码:
<div id="wrapper">
<header
ng-controller="HeaderController"
data-ng-class="headerType"
data-ng-include="'/templates/base/header.html'">
</header>
<section
ng-controller="SubheaderController"
data-ng-class="subheaderClass"
ng-repeat="subheader in subheaders"
data-ng-include="'/templates/base/subheader.html'">
</section>
<div
class="main"
data-ng-class="mainClass"
data-ng-view>
</div>
</div>
我需要 您可以创建自定义指令,使用 这将包括模板原样,没有任何包装元素,没有任何包装范围。 【讨论】: 编辑:经过一些研究并为了完整起见,我添加了一些信息。自 1.1.4 起,以下工作:
用法:
但是,有一个问题:模板不能是动态的(例如,通过作用域传递变量,因为 $scope 或任何DI 在 templateUrl 中无法访问 - 请参阅this issue),只能传递一个字符串(就像上面的 html sn-p 一样)。为了绕过这个特定问题,这段代码应该可以解决问题(感谢this plunker): 用法:
【讨论】: 对于碰巧访问此问题的任何人: 从 Angular 1.1.4+ 开始,您可以在 templateURL 中使用一个函数来使其动态化。 查看其他答案here 【讨论】: 通过正确的设置,您可以定义自己的 为了防止 Angular 内置指令执行,将指令的优先级设置为高于内置指令的优先级( 之后,你需要提供一个post-link函数来获取模板并将元素的DOM节点替换为编译后的模板HTML。 警告:这是相当严厉的,您为整个应用程序重新定义了 另外:这可能不适用于动画。原始 【讨论】: 其他一些答案建议 相反,在an answer to a similar question,我们找到了一个替代方案:它允许你写: 自定义指令: (从另一个答案中剪切'n'paste) 【讨论】: 以上是关于使用 nginclude 时避免使用额外的 DOM 节点的主要内容,如果未能解决你的问题,请参考以下文章 如何在 AngularJS 中为 ngInclude 指令指定模型? ngInclude 在 Android 的 PhoneGap 构建中失败templateUrl
属性链接到模板,并将replace
设置为true
:app.directive('myDirective', function()
return
templateUrl: 'url/to/template',
replace: true,
link: function(scope, elem, attrs)
);
templateUrl
配置中的templateUrl
。但也许您可以在该线程之后找到一些有趣的东西。 @filiptc【参考方案2】:
app.directive('include',
function ()
return
replace: true,
restrict: 'A',
templateUrl: function (element, attr)
return attr.pfInclude;
;
);
<div include="'path/to/my/template.html'"></div>
app.directive("include", function ($http, $templateCache, $compile)
return
restrict: 'A',
link: function (scope, element, attributes)
var templateUrl = scope.$eval(attributes.include);
$http.get(templateUrl, cache: $templateCache).success(
function (tplContent)
element.replaceWith($compile(tplContent.data)(scope));
);
;
);
<div include="myTplVariable"></div>
ng-include
,请检查它的来源如果您在此过程中遇到问题。干杯:)
非常好的(第二个例子)解决方案!它甚至适用于 元素,并且它们不会被扔出桌子:)!
已编辑:在第二个示例中将 【参考方案3】:
.data
添加到 tplContent
。 tplContent
是一个 HTTP 响应对象,而不是字符串,因此 $compile 会阻塞它。请在发布前测试代码!
ngInclude
指令来代替 Angular.js 提供的指令运行,并防止内置指令永远执行。ngInclude
为 400,并将 terminal
属性设置为 true
。 ngInclude
的行为。因此,我不是在myApp
上设置了下面的指令,而是在我自己的指令之一中设置了它以限制其范围。如果您想在应用程序范围内使用它,您可能希望使其行为可配置,例如如果在 HTML 中设置了 replace
属性并且默认回退到设置 innerHtml,则仅 替换 元素。 ngInclude
指令的代码要长得多,因此如果您在应用程序中使用动画,请复制原始代码并将`$element.replaceWith()
插入其中。var includeDirective = ['$http', '$templateCache', '$sce', '$compile',
function($http, $templateCache, $sce, $compile)
return
restrict: 'ECA',
priority: 600,
terminal: true,
link: function(scope, $element, $attr)
scope.$watch($sce.parseAsResourceUrl($attr.src), function ngIncludeWatchAction(src)
if (src)
$http.get(src, cache: $templateCache).success(function(response)
var e =$compile(response)(scope);
$element.replaceWith(e);
);
);
;
];
myApp.directive('ngInclude', includeDirective);
replace:true
,但请记住,模板中的replace:true
是marked for deprecation。<div ng-include src="dynamicTemplatePath" include-replace></div>
app.directive('includeReplace', function ()
return
require: 'ngInclude',
restrict: 'A', /* optional */
link: function (scope, el, attrs)
el.replaceWith(el.children());
;
);