0

I would like to use a custom directive that binds to an object, but I would like to specify the field used in the template. Previously, I was using {{item.Name}} but I would like to bind to any object, specifying the display field.

This is what I have

var foo = function () {
    return {
        restrict: 'E',
        scope: {
            items: '='
        },
        template:
        "<div class='holder'>"
          + "<a data-ng-repeat='item in items' data-ng-click='myClick(item)'><i class='fa fa-times'/>{{item.Name}}</a>"
          + "</div>",


        controller: function ($scope) {......}
      }
}

I'd like to do this:

var foo = function () {
    return {
        restrict: 'E',
        scope: {
            items: '=',
            display_field: 'Name',
            icon_field: 'fa fa-times',
        },
        template:
        "<div class='holder'>"
          + "<a data-ng-repeat='item in items' data-ng-click='myClick(item)'><i data-ng-class='{{item.icon_field}}'/>{{item.display_field}}</a>"
          + "</div>",


        controller: function ($scope) {......}
      }
}

Where the display_field and icon can be specified like this:

<foo items="myItems" display_field="OtherProperty" icon-field="iconProperty" />

fiddle: http://jsfiddle.net/1L7tdd1p/

1 Answer 1

1

You are close. Remember angular expressions are subsets of Javascript expressions. To access a property using a dynamic property name use bracket notation:

{{ item[display_field] }}

Any value can be a key for an object, not just strings. Bracket notation allows you to access a property of an object by using any expression as a key:

var obj = {};
obj[1] = 'a';
obj.asdf = 'b';
obj[{}] = 'c';
console.log(obj[1], obj['asdf'], obj[{}]);

Additionally, I think you misunderstood the purpose of the scope option. The scope option let's you specify a set of bindings your directive will pick up from the element you use it on, and the type of this bindings. You can't set default values with it. Have a look at Use of symbols '@', '&', '=' and '>' in custom directive's scope binding: AngularJS.

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

//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});

function MyCtrl($scope) {
  $scope.name = 'Superhero';
}

myApp.directive('foo', function() {
  return {
    restrict: 'E',
    scope: {
      items: '=',
      prop: '@' // this declared a
    },
    template: " <a data-ng-repeat='item in items'><br/>{{item[prop]}}</a>",

    controller: function($scope) {}
  }

});

myApp.controller("appController", function($scope) {
  $scope.Items = [{
    "id": 1,
    "name": "aaaa"
  }, {
    "id": 2,
    "name": "bbbb"
  }]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
<div ng-app='myApp' ng-controller="appController">
  <foo items="Items" prop='name'></foo>
</div>

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

2 Comments

Thanks for your quick help. For some reason that just doesn't work. It just shows blank. Even if I have a literal field called display_field. I tried to get it working in a fiddle jsfiddle.net/1L7tdd1p
Thanks! I guess I was close. My problem in the last bit was that I needed to use an @ instead of an =.

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.