I am using select2 to create a div with tags like functionality when creating a new post.
Stack is Angular 1.6.x
It works well when I am creating a new post BUT when I add pre-selected values when editing the said post, the preselected values never change from the default.
In a nutshell, the values are not binding.
See below:
HTML snippet:
<div class="form-group">
<label for="tags" class="control-label">Tags</label>
<select name="tags" class="tagsSearch" class="form-control" id="tags"
ng-options="tag as tag for tag in post.tags track by tag"
ng-model="post.tags" style="width: 100%" multiple>
</select>
</div>
Note: it looks messy but I got this to work to show my original tags
Controller snippet:
$http.get('/api/post', {params: { title: $scope.title }})
.then(function(res){
$scope.post = res.data.post;
});
$scope.updatePost = function() {
console.log($scope.post.tags);
};
The problem is that the tags do not bind, so if the values are: tag1, tag2, tag3 at rendering and I add: tag4 - updatePost consoles tag1, tag2 and tag3
PS: My tags are an array of strings and have no keys to it like an ID (saw some other post which was referencing to them).
Very lost. Any input would be highly appreciated.
Thanks
EDIT - 28th April 2018:
I have updated my tags to be objects of an array like this:
[
{tag: "tag1", _id: "5ae410756b7a61080cd17c81"},
{tag: "tag2", _id: "5ae410756b7a61080cd17c80"},
{tag: "tag3", _id: "5ae410756b7a61080cd17c7f"}
]
It still doesn't work when I do it like this:
<select name="tags" class="tagsSearch" class="form-control" id="tags"
ng-options="tag as tag.tag for tag in post.tags track by tag._id"
ng-model="post.tags" style="width: 100%" multiple>
</select>
The console.log still only captures the pre-existing tags. New ones are ignored.
ng-repeat creates a new scope for each iteration so will not perform as well as ng-options. For small lists, it will not matter, but larger lists should use ng-options. Apart from that, It provides lot of flexibility in specifying iterator and offers performance benefits over ng-repeat.
ng-bind is also used for data binding but unlike ng-bind it supports only one way data binding.It is used for displaying model properties as innerHTML of html elements such as div and span. This is unlike ng-model which is used for binding input fields and supports two way data binding.
Definition and Usage The ng-repeat directive repeats a set of HTML, a given number of times. The set of HTML will be repeated once per item in a collection. The collection must be an array or an object. Note: Each instance of the repetition is given its own scope, which consist of the current item.
Note that when an element is removed using ngIf its scope is destroyed and a new scope is created when the element is restored. The scope created within ngIf inherits from its parent scope using prototypal inheritance.
Below implementation might be what you asked for:
HTML:
<form name="myForm">
<label for="mySelect">Make a choice:</label>
<select name="mySelect" id="mySelect"
ng-options="option.tag for option in post.tag track by option._id"
ng-model="post.selected" multiple></select>
<br>
<button ng-click="updatePost()"> Add Tag</button>
</form>
JS:
(function(angular) {
'use strict';
angular.module('defaultValueSelect', [])
.controller('ExampleController', ['$scope', '$http', function($scope, $http) {
var url = "https://jsonblob.com/api/jsonBlob/aa6b4eb4-5284-11e8-a5ee-fd00735e3b38";
var index = 4;
var extraObj = {
tag: "tag",
_id: "5ae410756b7a61080cd17c7"
};
$http
.get(url)
.then(function(response) {
$scope.post = {
tag: response.data,
selected: response.data[0]
};
});
$scope.updatePost = function() {
var tmp = {};
tmp = angular.copy(extraObj);
console.log(angular.copy($scope.post));
tmp.tag += index;
tmp._id += index;
$scope.post.tag.push(tmp);
console.log($scope.post);
index++;
}
}]);
})(window.angular);
For working code refer to this plunkr: plnkr.co/edit/cwDRa2Qjg2IlUi5JOAPj
I used angular select documentation as a reference and created a plunker from their example found here.
I used this blob to simulate your data set.
This is what my select directive looks like. I would suggest that you not overwrite the binding for the array with the bind for the selected item, that is what is causing you problems.
(function(angular) {
'use strict';
angular.module('defaultValueSelect', [])
.controller('ExampleController', ['$scope','$http', function($scope,$http) {
var url = "https://jsonblob.com/api/jsonBlob/aa6b4eb4-5284-11e8-a5ee-fd00735e3b38";
$http
.get(url)
.then(function(response){
$scope.post = {
tag: response.data,
selected: response.data[0]
};
})
}]);
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="defaultValueSelect">
<div ng-controller="ExampleController">
<form name="myForm">
<label for="mySelect">Make a choice:</label>
<select name="mySelect" id="mySelect"
ng-options="option.tag for option in post.tag track by option._id"
ng-model="post.selected" multiple></select>
</form>
<hr>
<tt>option = {{post.selected}}</tt><br/>
</div>
</body>
Happy Coding
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With