I have a people array. The people array values are available in select. When I choose names, they are transferred to the multipleDemo
array. And you can not reselect them from select because they disappear and are moved to the multipleDemo
array. With the Delete button I have to delete all elements from the multipleDemo
array (except the first element) into the people array. So that you can again choose a name from the select. Error in function $clearTag
.
Expecting behavior: Example:
Here is my code: http://plnkr.co/edit/TPZjXkkSRrIc5ApzP07F?p=preview
index.html
<!DOCTYPE html>
<html lang="en" ng-app="demo">
<head>
<meta charset="utf-8">
<title>AngularJS ui-select</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular-sanitize.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.css">
<!-- ui-select files -->
<script src="select.js"></script>
<link rel="stylesheet" href="select.css">
<script src="demo.js"></script>
<!-- Select2 theme -->
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css">
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.default.css">
<style>
body {
padding: 15px;
}
.select2 > .select2-choice.ui-select-match {
/* Because of the inclusion of Bootstrap */
height: 29px;
}
.selectize-control > .selectize-dropdown {
top: 36px;
}
</style>
</head>
<body ng-controller="DemoCtrl">
<h3>Array of strings</h3>
<button ng-click='clearTag()'>Delete</button>
<ui-select tagging tagging-label="new tag" multiple ng-model="multipleDemo"
on-select="OnClickSelect($item)" on-remove="OnRemoveSelect($item)"
theme="select2" ng-disabled="disabled" style="width: 300px;">
<ui-select-match placeholder="Select name...">{{$item.name}}</ui-select-match>
<ui-select-choices repeat="item in people | filter:$select.search">
{{item.name}}
</ui-select-choices>
</ui-select>
<p>Selected: {{multipleDemo}}</p>
<hr>
</body>
</html>
demo.js
app.controller('DemoCtrl', function($scope, $http, $timeout) {
$scope.multipleDemo =[];
$scope.people = [
{ name: 'Adam', email: 'adam@email.com', age: 12, country: 'United States' },
{ name: 'Amalie', email: 'amalie@email.com', age: 12, country: 'Argentina' },
{ name: 'Estefanía', email: 'estefania@email.com', age: 21, country: 'Argentina' },
{ name: 'Adrian', email: 'adrian@email.com', age: 21, country: 'Ecuador' },
{ name: 'Wladimir', email: 'wladimir@email.com', age: 30, country: 'Ecuador' },
{ name: 'Samantha', email: 'samantha@email.com', age: 30, country: 'United States' },
{ name: 'Nicole', email: 'nicole@email.com', age: 43, country: 'Colombia' },
{ name: 'Natasha', email: 'natasha@email.com', age: 54, country: 'Ecuador' },
{ name: 'Michael', email: 'michael@email.com', age: 15, country: 'Colombia' },
{ name: 'Nicolás', email: 'nicolas@email.com', age: 43, country: 'Colombia' }
];
$scope.OnClickSelect=function(item)
{
$scope.multipleDemo.push(item.name);
}
$scope.OnRemoveSelect = function(item) {
var index = $scope.people.indexOf(item.name);
$scope.people.splice(index, 1);
}
$scope.clearTag = function() {
for(var i =0; i < $scope.multipleDemo.length; i++) {
$scope.multipleDemo.splice($scope.multipleDemo[i], 1000);
$scope.people.push($scope.multipleDemo[i]);
}
}
ng-model
not working with a simple variable on $scope
You cannot write:
WRONG
<ui-select ng-model="multipleDemo"> <!-- Wrong --> [...] </ui-select>
You need to write:
<ui-select ng-model="vm.multipleDemo"> <!-- Correct -->
[...]
</ui-select>
For more information, see
vm.multipleDemo
doesn't work; I try$parent.multipleDemo
- it works. I don't understand$parent
. Why it works?
For vm.multipleDemo
to work, the controller must initialize the vm
object:
app.controller('DemoCtrl', function($scope, $http, $timeout) {
$scope.vm = { multipleDemo: [] };
New AngularJS developers often do not realize that
ng-repeat
,ng-switch
,ng-view
,ng-include
andng-if
all create new child scopes, so the [data hiding] problem often shows up when these directives are involved. (See this example for a quick illustration of the problem.)This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with
ng-switch
.— What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
Avoid using $parent
to fix a data hiding problem. It is a brittle solution as there can be more than one level of scope heirarchy between the controller and the ui-select
directive. I consider the use of $parent
to be a code smell, a symptom of a deeper problem.
When I can use
$ctrl
in view andthis
in controller?
If the controller is instantiated with "controller as" syntax:
<body ng-controller="DemoCtrl as $ctrl">
<ui-select ng-model="$ctrl.multipleDemo">
<!-- -->
</ui-select>
Then there is no need to use $scope
:
app.controller('DemoCtrl', function($http) {
this.multipleDemo = [];
And it avoids the data hiding problem.
For more information, see