admin管理员组

文章数量:1321446

I keep bumping my head on angular when I want to have a directive that displays a list of things, but I want it to be generic enough to handle more than one type/shape of object. For simple example lets say I have

<select ng-options="person.id by person in people" ng-model="selectPerson">
  <option>
     {{person.name}}
  </option>
</select>

(Keep in mind that this is a simple example and something this simple would probably not benefit from being a directive)

Now I want to turn it into a generic directive called cool-select I might try and do something like this in my js

//directive coolselect.directive.js
angular.module('mycoolmodule',[]).directive('coolSelect',function(){
    return {
       restrict:'E',
       templateUrl:'js/coolselectdirective/_coolselect.html',//html from example above
       scope:{
             items:'=',
             displayProperty:'@',
             idProperty:'@',
             selectedItem:'='
       },
       link:function(scope,element){
        //do cool stuff in here
       }
   }
});

But then here is where I start to throw up a little in my mouth

//html template _coolselect.html
<select ng-model="selectedItem" ng-options="item[scope.idProperty] by item in items">
  <option>      
     {{item[scope.displayProperty]}}
   </option>
</select>

To be perfectly honest I am not even sure this would work in angular. I have seen what ui-select does by using an outer scope. Maybe that is the way to go? .js#L892

But then I think I would need to get fancy with transclude, like ui-select does. Isn't there an easier way? Am I trying to make directives to generic? Is this not a problem other people are running into?

EDIT: In the end it would be ideal for it to look like this.

<cool-select repeat="person.id by person in people" display-property="name"></cool-select>

I keep bumping my head on angular when I want to have a directive that displays a list of things, but I want it to be generic enough to handle more than one type/shape of object. For simple example lets say I have

<select ng-options="person.id by person in people" ng-model="selectPerson">
  <option>
     {{person.name}}
  </option>
</select>

(Keep in mind that this is a simple example and something this simple would probably not benefit from being a directive)

Now I want to turn it into a generic directive called cool-select I might try and do something like this in my js

//directive coolselect.directive.js
angular.module('mycoolmodule',[]).directive('coolSelect',function(){
    return {
       restrict:'E',
       templateUrl:'js/coolselectdirective/_coolselect.html',//html from example above
       scope:{
             items:'=',
             displayProperty:'@',
             idProperty:'@',
             selectedItem:'='
       },
       link:function(scope,element){
        //do cool stuff in here
       }
   }
});

But then here is where I start to throw up a little in my mouth

//html template _coolselect.html
<select ng-model="selectedItem" ng-options="item[scope.idProperty] by item in items">
  <option>      
     {{item[scope.displayProperty]}}
   </option>
</select>

To be perfectly honest I am not even sure this would work in angular. I have seen what ui-select does by using an outer scope. Maybe that is the way to go? https://github./angular-ui/ui-select/blob/master/dist/select.js#L892

But then I think I would need to get fancy with transclude, like ui-select does. Isn't there an easier way? Am I trying to make directives to generic? Is this not a problem other people are running into?

EDIT: In the end it would be ideal for it to look like this.

<cool-select repeat="person.id by person in people" display-property="name"></cool-select>
Share Improve this question edited Jan 30, 2015 at 19:56 Thomas Florin asked Jan 30, 2015 at 15:40 Thomas FlorinThomas Florin 4036 silver badges14 bronze badges 3
  • You should use the directive as an element and you use it as a class? When you change the restrict E to C, you can use it as an class. – R Pelzer Commented Jan 30, 2015 at 15:53
  • Sorry the class, is just to show that there are custom styles associated with this element. – Thomas Florin Commented Jan 30, 2015 at 19:50
  • I took out the class to make it more clear – Thomas Florin Commented Jan 30, 2015 at 19:50
Add a ment  | 

3 Answers 3

Reset to default 5

Please see demo below how to pass each object from array to directive in ng-repeater

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

app.controller('homeCtrl', function($scope) {


  $scope.people = [{
    name: "John"
  }, {
    name: "Ted"
  }]

});

app.directive('user', function() {

  return {

    restrict: 'EA',
    template: "<p>*name:{{user.name}}</p>",
    scope: {
      user: '='
    },
    link: function(scope, element, attr) {

      console.log(scope.user);
    }
  };

});
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app">
  <div ng-controller="homeCtrl">

    <div ng-repeat="person in people" user="person"></div>

  </div>
</div>

There are a few things to note here:

  1. By placing ng-repeat on the select you are repeating the select.
  2. The select element has a special attribute for repeating options called ng-options.
  3. You don't need to refer to the scope in the template, just its properties. In an AngularJS template scope is implied, in fact that's the purpose of scope, to be the "scope" that you are accessing properties within.
  4. You are not instantiating the coolSelect directive because you have restricted it to being used as an element but you are trying to use it as a class.
  5. If you want to make a directive to simplify this process each time you want to repeat options or other ponents you will need to use syntax like item[displayProperty] in order to make it generic.

Why you need to build the options yourself with displayProperty in options tag ng-options can do more

<select
ng-model="myOption"
ng-options="value.id as value.label  for value in myOptions">
<option value="">nothing selected Text</option>
</select>

value.id is the value stored in the ngModel myOption value.label is the displayed label

<option value="">nothing selected Text</option>

for having a nothing selected option if necessary

本文标签: javascriptpassing data to a directive for ngrepeat inside of the directiveStack Overflow