Jquery AngularJS-无法在链接函数中动态更改指令模板 当心
接受的解决方案将使用Jquery AngularJS-无法在链接函数中动态更改指令模板 当心,jquery,angularjs,templates,angularjs-directive,promise,Jquery,Angularjs,Templates,Angularjs Directive,Promise,接受的解决方案将使用replace:true:HTML将不会被替换,使用中的特定CSS选择器将不再工作,等等来破坏指令 我希望我的指令通过观察作为属性从父控制器接收的字符串来动态更改其模板,因此我使用了$compilefrom和$observefrom,但可惜它不起作用,如中所示 关于错误 如果脚本中在AngularJS之前包含jQuery,则调用replaceWith会抛出以下错误: TypeError: Cannot read property 'ownerDocument' of und
replace:true
:HTML将不会被替换,使用中的特定CSS选择器将不再工作,等等来破坏指令
我希望我的指令通过观察作为属性从父控制器接收的字符串来动态更改其模板,因此我使用了
$compile
from和$observe
from,但可惜它不起作用,如中所示
关于错误
如果脚本中在AngularJS之前包含jQuery,则调用replaceWith
会抛出以下错误:
TypeError: Cannot read property 'ownerDocument' of undefined
但是如果我删除jQuery,迫使AngularJS使用它的jqLite,同样的部分会抛出这个错误,让像我这样完全不懂jQuery的人更清楚:
即使我很清楚我没有将有效的“节点”类型对象传递给replaceWith
,我也不知道如何处理这种情况,因为我希望$compile
来完成这项工作
我只知道,console.log(tplContent)
看起来像这样(一个承诺,我说得对吗?):
我真的很想避免使用以下两种方法中的任何一种,你知道我做错了什么吗
后备队,又名,别让我这么做 我知道我可以将指令分为两个指令,如果它们是这样的话,
ng
(function() {
'use-strict';
angular.module('app')
.directive('dynamicTemplateA', dynamicTemplate);
DynTplCtrl.$inject = ['$http', '$templateCache', '$compile', '$parse'];
function dynamicTemplate($http, $templateCache, $compile, $parse) {
var directive = {
restrict: 'E',
templateUrl: 'template-a.html',
scope: {},
bindToController: {
tpl: '@',
i: '='
},
controller: DynTplCtrl,
controllerAs: 'dyntplctrl',
link: linkFunc
}
return directive;
function linkFunc(scope, el, attrs, ctrl) {}
}
DynTplCtrl.$inject = [];
function DynTplCtrl() {}
})()
(function() {
'use-strict';
angular.module('app')
.directive('dynamicTemplateB', dynamicTemplate);
DynTplCtrl.$inject = ['$http', '$templateCache', '$compile', '$parse'];
function dynamicTemplate($http, $templateCache, $compile, $parse) {
var directive = {
restrict: 'E',
templateUrl: 'template-b.html',
scope: {},
bindToController: {
tpl: '@',
i: '='
},
controller: DynTplCtrl,
controllerAs: 'dyntplctrl',
link: linkFunc
}
return directive;
function linkFunc(scope, el, attrs, ctrl) {}
}
DynTplCtrl.$inject = [];
function DynTplCtrl() {}
})()
然后在controller.html
中:
<div ng-repeat="i in [1,2,3]">
<dynamic-template-a ng-if="mainctrl.tpl === 'a'" tpl="{{mainctrl.tpl}}" i="i"></dynamic-template-a>
<dynamic-template-b ng-if="mainctrl.tpl === 'b'" tpl="{{mainctrl.tpl}}" i="i"></dynamic-template-b>
</div>
归功于
替换模板时,您需要稍微更改代码:
el.html(tplContent.data);
$compile(el.contents())(scope);
这将替换元素的内容(尽管您需要在此处处理清理),然后在指令的范围内编译模板
另外,为了进行测试,我已经从template-a.html
和template-b.html
中删除了
标记
这是一个具有上述更改的脚本。您不必将HTML
放入脚本标记中。只需将普通HTML存储在文件中,如
模板-a.html
<p>TEMPLATE A</p>
为什么不这样做呢?这是第二个退路,是我采用的实际实现,我正试图摆脱它;但我面临的第一个问题是,其中一个模板无法达到指令中包含的样式规则。less
文件位于同一文件夹中(您在plunkr中找不到这个问题,我还没有更新它)。当然,当它不需要在两个模板之间动态切换时,它就能够到达它们;这是;在我看来,这是正确的答案。Upvoted@Gargaroz-请检查此答案是否解决了您的问题。感谢@31piy甚至提供了一个我一开始找不到的源代码。@31piy此解决方案中只有一个缺陷:它将破坏带有replace:true
的指令,这意味着不会替换任何内容,并且使用的特定CSS选择器将不再工作。我在谷歌上搜索了一下这个问题,但遗憾的是,我找不到一个解决方案,即使用动态模板来替换HTML:你对此有什么见解/建议吗?
<div ng-repeat="i in [1,2,3]">
<dynamic-template-a ng-if="mainctrl.tpl === 'a'" tpl="{{mainctrl.tpl}}" i="i"></dynamic-template-a>
<dynamic-template-b ng-if="mainctrl.tpl === 'b'" tpl="{{mainctrl.tpl}}" i="i"></dynamic-template-b>
</div>
(function() {
'use-strict';
angular.module('app')
.directive('dynamicTemplateA', dynamicTemplate);
DynTplCtrl.$inject = ['$http', '$templateCache', '$compile', '$parse'];
function dynamicTemplate($http, $templateCache, $compile, $parse) {
var directive = {
restrict: 'E',
template: '<div ng-include="dyntplctrl.getTemplateUrl()"></div>',
scope: {},
bindToController: {
tpl: '@',
i: '='
},
controller: DynTplCtrl,
controllerAs: 'dyntplctrl',
link: linkFunc
}
return directive;
function linkFunc(scope, el, attrs, ctrl) {}
}
DynTplCtrl.$inject = [];
function DynTplCtrl() {
var vm = this;
vm.getTemplateUrl = _getTemplateUrl;
function _getTemplateUrl() {
return 'template-' + vm.tpl + '.html';
}
}
})()
el.html(tplContent.data);
$compile(el.contents())(scope);
<p>TEMPLATE A</p>
function(tplContent) {
var content = $compile(tplContent.data)(scope);
if(el[0].childNodes.length){
el[0].removeChild(el[0].childNodes[0]);
}
el.append(content);
}