sanikeev sanikeev - 5 months ago 8
Javascript Question

How to add item list to controller scope from directive which create many select tags


  1. I have controller with $scope.usersList

  2. I have directive wich create many select tags
    See this link

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





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


app.directive('adduser',function($compile){
return {
restrict: 'A',

link: function(scope, elem, attr) {

var tmpl = '<select class="js-select" ng-model="userItem[key]">'
+'<option></option>'
+'<option ng-repeat="item in users" value="item.id">{{item.login}}</option>'
+'</select>';
scope.key = 0;
elem.on('click', function (e) {
scope.users = [{id:1, login: 'admin'},{id:2, login: 'guest'}];
var tmplCompiled = $compile(tmpl);
e.preventDefault();
elem.parent().prepend(tmplCompiled(scope));
scope.key++;
});
}
};
});
app.controller('AppController',function($scope){
// pass user list here
});

<!DOCTYPE html>
<html>

<head>
<script data-require="angularjs_1_3_15@1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.min.js"></script>
<script data-require="angularjs_1_3_15@1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular-animate.min.js"></script>
<script data-require="angularjs_1_3_15@1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular-aria.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" data-semver="3.3.5" data-require="bootstrap@3.3.5" />
<link href="style.css" rel="stylesheet" />
<script src="script.js"></script>
</head>

<body ng-app="app">
<div ng-controller="AppController">
<div>
<a adduser class="btn btn-default" href="javascript:void(0)" > Add </a>
</div>
</div>
<div>{{userItem | json}}</div>
</body>

</html>





directive generated



<select ng-model="userItem">...</select>
<select ng-model="userItem">...</select>
...





I need get
userItem
as list of selected items.

How can I get it?

Joy Joy
Answer

Check the working demo at Plunker and the console as well.

I actually rewrote your code completely. Your original code is totally not Angular style for these reasons:

  1. Call $compile (should be avoided wherever possible)
  2. Use click event on elements
  3. Not using the strongest power of Angular: bindings.

Please check my code:

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

app.directive('adduser',function($compile){
  return {
    restrict: 'A',
    scope: {
      users: '='
    },
    template: 
      '<div>' +
        '<div ng-repeat="u in users">' +
          '<select ng-model="u.role" ng-options="r.login for r in defaultRoles"></select>' +
        '</div>' +
        '<button ng-click="add()">Add New</button>' +
      '</div>',
    controller: ['$scope', function ($scope) {
      $scope.defaultRoles = [{id:1, login: 'admin'},{id:2, login: 'guest'}];
      $scope.add = function () {
        $scope.users.push({
          role: $scope.defaultRoles[1]
        });
      };
    }]
  };
});
app.controller('AppController',function($scope){
    // pass added user list here
    $scope.users = [];
    $scope.$watch('users', function () {
      console.log($scope.users);
    }, true);
});