angularjs custom directive conditional templateUrl via attribute

孤人 提交于 2020-01-02 09:32:39

问题


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';
     }

回答1:


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.



来源:https://stackoverflow.com/questions/30672809/angularjs-custom-directive-conditional-templateurl-via-attribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!