0

I have the following element in my Angular template to generate a button bar with Font Awesome icons:

<li 
    data-ng-repeat="btn in navigation.buttonBar" 
    data-ng-click="{{ btn[1] }}"
    class="btn btn-default" style="font-size: 30px; vertical-align: middle;"
    tooltip-placement="bottom" tooltip="{{ btn[2] }}">
        <i class="fa {{ btn[0] }}"></i>
</li>

navigation.buttonBar is the following array of arrays:

[
    [ "fa-minus", "less()", "Show fewer cloud buttons." ],
    [ "fa-plus", "more()", "Show more cloud buttons." ],
    [ "fa-minus-square", "smaller()", "Make cloud buttons smaller." ],
    [ "fa-plus-square", "bigger()", "Make cloud buttons bigger." ],
    [ "fa-bars", "toggleShowStrings()", "Toggle display of matching strings." ],
    [ "fa-refresh", "initialize();", "Load more content." ],
    [ "fa-undo", "resetQuery()", "Clear query." ]
]

The text and icons render correctly, but the resulting buttons don't work. When I inspect the element, I see that btn[1] was expanded correctly. What do I replace {{ btn[1] }} with to make this work properly?

2
  • What do you mean with "buttons don't work"? Any error? Do you have a Punkler or JSFiddle? Commented Oct 1, 2014 at 22:41
  • @denisazevedo OP's issue is with ng-click, trying to dynamically assign function expression using binding. Commented Oct 1, 2014 at 23:41

1 Answer 1

2

I don't think you can just assign the function expression as string from a binding. If you try to use interpolation it is going to throw syntax error, If you use it as binding it is of no use as well. Instead you would need to probably use $parse and do something like this.

app.controller('MainCtrl',['$scope', '$parse', function($scope, $parse) { //<-- inject parse
    //.. Some code

    //Make this as handler to ngClick passing expression which is function name you have in your model
    $scope.callFunc = function(exp){
       $parse(exp)($scope); //Parse the function name to get the expression and invoke it on the scope
    }
    //Your specific function to be called
    $scope.less = function(){
      console.log('less');
    }
    $scope.more = function(){
      console.log('more');
    }

In your view do:-

     data-ng-click="callFunc(btn[1])"

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, $parse) {
  $scope.navigation = {buttonBar:[
    [ "fa-minus", "less()", "Show fewer cloud buttons." ],
    [ "fa-plus", "more()", "Show more cloud buttons." ],
    [ "fa-minus-square", "smaller()", "Make cloud buttons smaller." ],
    [ "fa-plus-square", "bigger()", "Make cloud buttons bigger." ],
    [ "fa-bars", "toggleShowStrings()", "Toggle display of matching strings." ],
    [ "fa-refresh", "initialize();", "Load more content." ],
    [ "fa-undo", "resetQuery()", "Clear query." ]
]};

  $scope.callFunc = function(exp){
    $parse(exp)($scope);
  }
  
  $scope.less = function(){
    console.log('less');
  }
  
  $scope.more = function(){
   console.log('more');
  }
});
    <link data-require="bootstrap-css@*" data-semver="3.2.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="https://code.angularjs.org/1.2.25/angular.js" data-semver="1.2.25"></script>




  <div ng-app="plunker" ng-controller="MainCtrl">
     <i>Click the first 2 buttons and check the console</i>
    <ul><li 
    data-ng-repeat="btn in navigation.buttonBar" 
    data-ng-click="callFunc(btn[1])"
    class="btn btn-default" style="font-size: 30px; vertical-align: middle;"
    tooltip-placement="bottom" tooltip="{{ btn[2] }}"
><i class="fa {{ btn[0] }}"></i></li></ul>
 </div>

Sign up to request clarification or add additional context in comments.

1 Comment

I know it's old, but how would I pass the $event using this $parse-solution?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.