问题描述
我正在尝试通过属性加载条件模板网址,我的指令如下.
指令在 ng-repeate 中,当 box.key == 'experiences' 时,表达式返回的是 education-form.php 而不是 Experience-form.php.
指令 DDO
{限制:'A',替换:真的,范围: {指令数据:'=',onsave: '&',onreset: '&',取消: '&',表单名称: '@',形式:'=',项目:'='},控制器:控制器,模板网址:函数(tElement,tAttrs){返回 $rootScope.$eval(tAttrs.templateUrl);}}
尝试使用链接功能
控制器:控制器,链接:函数(范围,元素,属性){//显示正确的模板 url ... 现在怎么办?console.log(scope.templateMap[scope.box.key]);},模板网址:功能(tElement,tAttrs){返回'经验-form.php';}
标记
那么你的 templateUrl 函数将是
templateUrl: function(tElement, tAttrs) {$timeout(function(){//等到 ng-attr 评估一个值.返回 tAttrs.templateUrl;})}
不确定它是否有效.
更新
另一种明显的方法是从链接函数加载模板并从那里自己附加它,而不是通过 templateUrl
HTML
指令
{限制:'A',替换:真的,范围: {指令数据:'=',onsave: '&',onreset: '&',取消: '&',表单名称: '@',形式:'=',项目:'=',模板路径:'@'},控制器:控制器,链接:功能(范围,元素,属性){//这里你的scope.templatePath变量中有模板路径//您可以使用它加载模板.var 模板 = getTemplate();//这可以通过下面提到的方式完成element.append($compile(template)(scope));//添加编译元素}}
在你的链接函数中,你可以通过按需加载模板来附加指令模板,有几种方法可以从指令加载模板
使用 $templateCache
在使用 $templateCache
时,您需要在运行阶段将该模板放在有角度的 $templateCache
中,
app.run(function($templateCache){$templateCache.put('myTemplate.html', '<div>myTemplate</div>')})
执行此操作后,您可以通过添加 $templateCache.get('myTemplate.html')
在 $templateCache
中添加模板的另一种方法是使用 script
标签和 type="text/ng-template"
使用 $http.get
您可以通过使用 $http.get('myTemplate.html')
获取模板,如果成功,您将获得该文件的 html 内容数据.您可以编译该 html 并将其附加到您的指令元素中.
使用 ng-include
你可以在这里使用 ng-include 指令.您需要创建一个虚拟 div,它将具有一个带有所需 template-path
的 ng-include 指令,例如 <div ng-include="templatePath"></div>
,它将在该 div 中加载一个模板.如果您不想使用 div,那么您可以使用 <ng-include src="templatePath"></ng-include>
.但这并不是编写代码的更可取的方式.因为它确实像 ng-repeat 一样创建了子作用域.
I am trying to load conditional template urls via attributes, my directives is as follows.
The directive is in a ng-repeate and when box.key == 'experiences' the expression is returning education-form.php and not experiences-form.php.
<div multiple-form
directive-data='directiveData'
template-url="box.key == 'experiences'? 'experiences-form.php':'education-form.php'"
item="item"
forms="forms"
form-name="{{box.key}}{{item._id}}"
onsave="updateMultipleUser(box.key, item._id, $data)"
onreset="formAction($formName, 'reset')"
cancel="formAction($formName, 'cancel')"
>
</div>
Directive DDO
{
restrict: 'A',
replace: true,
scope: {
directiveData: '=',
onsave: '&',
onreset: '&',
cancel: '&',
formName: '@',
forms: '=',
item: '='
},
controller: controller,
templateUrl: function(tElement, tAttrs) {
return $rootScope.$eval(tAttrs.templateUrl);
}
}
attempting using link function
<div multiple-form
directive-data='directiveData'
template-map="{
experiences:'experiences-form.php',
courses:'education-form.php'
}"
box="box"
item="item"
forms="forms"
form-name="{{box.key}}{{item._id}}"
onsave="updateMultipleUser(box.key, item._id, $data)"
onreset="formAction($formName, 'reset')"
cancel="formAction($formName, 'cancel')"
>
</div>
controller: controller,
link: function(scope, element, attrs) {
// shows correct template url ... now what?
console.log(scope.templateMap[scope.box.key]);
},
templateUrl: function(tElement, tAttrs) {
return 'experiences-form.php';
}
Markup
<div multiple-form
directive-data='directiveData'
ng-attr-template-url="{{box.key == 'experiences'? 'experiences-form.php':'education-form.php'}}"
item="item"
forms="forms"
form-name="{{box.key}}{{item._id}}"
onsave="updateMultipleUser(box.key, item._id, $data)"
onreset="formAction($formName, 'reset')"
cancel="formAction($formName, 'cancel')"
>
</div>
Then your templateUrl function would be
templateUrl: function(tElement, tAttrs) {
$timeout(function(){ //wait until the ng-attr evaluates a value.
return tAttrs.templateUrl;
})
}
Not sure it will work or not.
Update
Another obivious way would be loading template from the link function and append it from there it self rather than having call template through templateUrl
HTML
<div multiple-form
directive-data='directiveData'
template-path="{{box.key == 'experiences'? 'experiences-form.php':'education-form.php'}}"
item="item"
forms="forms"
form-name="{{box.key}}{{item._id}}"
onsave="updateMultipleUser(box.key, item._id, $data)"
onreset="formAction($formName, 'reset')"
cancel="formAction($formName, 'cancel')">
</div>
Directive
{
restrict: 'A',
replace: true,
scope: {
directiveData: '=',
onsave: '&',
onreset: '&',
cancel: '&',
formName: '@',
forms: '=',
item: '=',
templatePath: '@'
},
controller: controller,
link: function(scope, element, attrs){
//here you will have template path in your scope.templatePath variable
//you can load template using it.
var template = getTemplate(); //this can be done by below mentioned way
element.append($compile(template)(scope));//addding compiled element
}
}
Inside your link function you could append directive template by loading template on demand, there are several way to load template from directive
Using $templateCache
While using $templateCache
you need to put that template in angular $templateCache
at the run phase,
app.run(function($templateCache){
$templateCache.put('myTemplate.html', '<div>myTemplate</div>')
})
After doing this you could eaisily access that template in directive just by adding $templateCache.get('myTemplate.html')
Another way of adding template in $templateCache
would be using script
tag with type="text/ng-template"
<script type="text/ng-template" id="myTemplate.html">
<div>myTemplate</div>
</script>
Using $http.get
You could do get the template by using $http.get('myTemplate.html')
in success of it you will get data that is nothing but html content that file. You could compile and append that html to your directive element.
Using ng-include
You could use ng-include directive here. You need to do create a dummy div that will have an ng-include directive with desired template-path
like <div ng-include="templatePath"></div>
,it will load a template in that div. If you don't want to use div then you could use <ng-include src="templatePath"></ng-include>
. But this is not much preferable way of doing code. because it does create child scope like ng-repeat does.
这篇关于angularjs 自定义指令条件 templateUrl 通过属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!