在angularjs指令中引用正确的名称

时间:2013-07-30 04:03:49

标签: angularjs angularjs-directive

所以我编写了一个angularjs指令来简化下拉列表的呈现:

'use strict';

angular.module('myApp')
  .directive('filterDropdowns', function () {
    return {
      restrict: 'A',
      template: '<a class="wrapper-dropdown" data-dropdown="{{ labelData }}">{{ label }}</a>' +
                '<ul id="{{ labelData }}" class="f-dropdown">' + 
                  '<li ng-repeat="item in items">' + 
                    '<a ng-click="setFilter(item.district)">{{ item.district }}</a>' +
                  '</li>' +
                '</ul>',
      scope: {
        label: '@label',
        labelData: '@labelData',
        dropdownValue: '=' // expects an object from the directive
      },
      link: function (scope, element, attrs) {
        scope.$watch('dropdownValue', function(dropdownValue) {
          if (dropdownValue) {
            scope.items = dropdownValue;
          }
        });
      }
    };
  });

我可以通过这种方式在我的观看中轻松使用: -

<div filter-dropdowns label="Districts" label-data="districts-data" dropdown-value="districts"></div>

<div filter-dropdowns label="Countries" label-data="countries-data" dropdown-value="countries"></div>

问题在于我的指令中使用了{{ item.district }}

根据我传递给我的指令的对象列表,我实际上需要渲染{{ item.country }}{{ item.area }},因此我不应该是硬编码 {{ item.district }}我的指令模板或将item.district传递给setFilter()

解决此问题的好方法是什么,以便我不需要在我的指令代码中硬编码{{ item.district }}或将item.district传递给setFilter()

2 个答案:

答案 0 :(得分:3)

允许指令的用户指定要使用的项密钥名称(可能称为“displayableItemKey”):

<!-- Proposed usage -->
<div filter-dropdowns label="Districts" label-data="districts-data"
     dropdown-value="districts" displayable-item-key="district"></div>

然后链接到您的指令范围:

scope: {
  ...,
  displayableItemKey: '@'
},

最后在指令模板中:

...
'<a ng-click="setFilter(item[displayableItemKey])">{{ item[displayableItemKey] }}</a>' +
...

答案 1 :(得分:0)

您可以使{{ item.district }}更加通用,例如{{ item.name }},您可以将数据源从区域转换为名称,然后传入指令。请看一下这段代码。

Demo on Fiddle

function Cntl($scope) {
    var districts = [{
        district: "PA"
    }, {
        district: "NJ"
    }, {
        district: "MD"
    }];

    $scope.districts = [];
    angular.forEach(districts, function (item) {
        $scope.districts.push({
            name: item.district
        });
    });

    var countries = [{
        district: "USA"
    }, {
        district: "Mexico"
    }];
    $scope.countries = [];
    angular.forEach(countries, function (item) {
        $scope.countries.push({
            name: item.district
        });
    });
}

angular.module('MyApp', []).directive('filterDropdowns', function () {
    return {
        restrict: 'A',
        template: '<a class="wrapper-dropdown" data-dropdown="{{ labelData }}">{{ label }}</a>' +
            '<ul id="{{ labelData }}" class="f-dropdown">' +
            '<li ng-repeat="item in items">' +
            '<a ng-click="setFilter(item.name)">{{ item.name }}</a>' +
            '</li>' +
            '</ul>',
        scope: {
            label: '@label',
            labelData: '@labelData',
            dropdownValue: '=' // expects an object from the directive
        },
        link: function (scope, element, attrs) {
            scope.$watch('dropdownValue', function (dropdownValue) {
                if (dropdownValue) {
                    scope.items = dropdownValue;
                }
            });
        }
    };
});