Passing value of a variable to angularjs directive template function

后端 未结 3 1455
长发绾君心
长发绾君心 2021-02-04 11:03

I am trying to pass a $scope\'s variable to a directive, but its not working. I am catching the variable in the template function:

app.directive(\'customdir\', f         


        
相关标签:
3条回答
  • 2021-02-04 11:17

    First of all, what is a template function? It should be a link function. Second, you're overloading the link function incorrectly, order matters here, its always scope, element, attrs .Third, pass the variable in an isolate scope:

    app.directive('customdir', function ($compile) {
    
        return {
            restrict: 'E',
            scope:{
              filterby:'='
            },
    
            link: function(scope,element, attrs) {
                console.log(scope.filterby);
                switch (scope.filterby) {
                    case 'World':
                        return '<input type="checkbox">';
                }
                return '<input type="text" />';
            }
        };
    });
    

    or if you insist on attributes then:

     app.directive('customdir', function ($compile) {
    
            return {
                restrict: 'E',
    
                link: function(scope,element, attrs) {
                    console.log(attrs.filterby);
                    switch (attrs.filterby) {
                        case 'World':
                            return '<input type="checkbox">';
                    }
                    return '<input type="text" />';
                }
            };
        });
    

    but in your html:

     <customdir filterby="{{name}}"></customdir>
    

    To ensure the variables value gets evaluated first. Finally you should not be manipulating the DOM like that, in fact that link function won't render html as you'd expect. You have a static template and your link function will act as something to set variable values on the template.

    0 讨论(0)
  • 2021-02-04 11:32

    Or like this

    app.directive('customdir', function ($compile) {
      var getTemplate = function(filter) {
        switch (filter) {
          case 'World': return '<input type="checkbox" ng-model="filterby">';
          default:  return '<input type="text" ng-model="filterby" />';
        }
      }
    
        return {
            restrict: 'E',
            scope: {
              filterby: "="
            },
            link: function(scope, element, attrs) {
                var el = $compile(getTemplate(scope.filterby))(scope);
                element.replaceWith(el);
            }
        };
    });
    

    http://plnkr.co/edit/yPopi0mYdViElCKrQAq9?p=preview

    0 讨论(0)
  • 2021-02-04 11:32

    Template should not contain logic because template is view. Template should only contain binding directives to make the view updated based on changes of the scope (model). Something like this:

    app.directive('customdir', function ($compile) {
    
        return {
            restrict: 'E',
    
            scope:{
              filterby:"="
            },
    
            link:function (scope, element) {
              scope.$watch("filterby",function(newValue){ //logic is out of template
                  if (newValue == "World"){
                    scope.showCheckBox = true;
                  }
                  else {
                    scope.showCheckBox = false;
                  }
              });
            },
    
            template: function(element, attrs) {
             //View should be passive and only listens to changes of model to update it accordingly.
                return '<input type="checkbox" ng-show="showCheckBox" / ><input type="text" ng-show="!showCheckBox"  />'; 
            }
        };
    });
    

    With this approach, you could even change the input at runtime and the view is updated to reflect the changes.

    DEMO

    If you want to make a decision on which template to use based on some configuration, you should configure it via a normal property, should not access though scope's propery. Simply like this:

    app.directive('customdir', function ($compile) {
    
        return {
            restrict: 'E',
            scope: {
                filterby:"=" //filterby is a separate field used for data binding
            },
    
            template: function(element, attrs) {
                switch (attrs.type) { //view selection configuration should be obtained from the element
                    case 'checkbox':
                        return '<input type="checkbox">';
                }
                return '<input type="text" />';
            }
        };
    });
    

    Configure it by passing a normal value:

    <customdir type="checkbox" filterby="name"></customdir>
    

    DEMO

    0 讨论(0)
提交回复
热议问题