Save model as modified value
This is part of the code I'm currently working with:
<select ng-model="rule.platforms" ng-options="platform for platform in platforms"
name="platform" multiple required>
<option value="">-- platform --</option>
</select>
The default behavior for multiple selection in Angular is to bind an array to a model. For example:
rule.platforms = ["twitter", "google"]
However, due to the way this needs to be stored in the database, all values ββneed to be concatenated into one row. Right now, the clearest solution is to parse the value just before saving / updating, but this will add a lot of logic as it will have to go through all the data and check each rule.
What I really would like to do is be able to change the way the model bound value is bound initially, so instead of the above it will save with a value like this:
rule.platforms = "twitter, google"
Is it possible? I've been going through the Angular documentation but haven't come across anything like it. If anyone knows that there is a simple way to achieve this behavior, please let me know!
** EDIT **
To clarify my specific use case, I wanted to include the data structure in question:
$scope.data =
{
project: {
name: "",
topics_attributes: [
{
name: "",
feed_size: "",
topic_sources_attributes: [
{
platform: "",
keywords: "",
authors: ""
}
],
rules_attributes: [
{
name: "",
platforms: "",
conditional: "",
terms: ""
}
]
}
]
}
}
The problem is with rules_attributes.platforms as rules_attributes and all its children are dynamically created. If it was a static model parameter, then Mike's solution would work fine. Unfortunately, the dynamic nature of the model makes it difficult to change as suggested.
source to share
As far as I know, the simplest way to achieve this would be to use a temporary variable area to store platforms. Then you can watch the temporary variable to change with $ watch, analyze the value, and update your rules. String value platforms.
Edit: I imagined that you have something similar to this very simplistic approach:
http://jsfiddle.net/oqwh5gs7/12/
function MyCtrl($scope) {
$scope.rule = {};
$scope.rule.platforms = ['google'];
$scope.tempPlatforms = [];
$scope.platforms = ['google', 'twitter'];
for(var i in $scope.rule.platforms) {
$scope.tempPlatforms[i] = $scope.rule.platforms[i];
}
$scope.$watch('tempPlatforms', function(newValue, oldValue) {
$scope.rule.platforms = newValue.join();
});
}
If the available platforms are installed, there should be no problem updating the correct rule. You can put the selection inside a directive and pass the current rule through "=" or "&". depending on your needs. If the platforms available change according to the current rule, it can get a little more difficult, of course ...
EDIT: I'm still not sure if I understood the problem correctly, but I updated my script to dynamically create new rules to demonstrate how I represent your problem: http://jsfiddle.net/oqwh5gs7/16/
Essentially, I only created a select directive and added $ scope. $ watch ('rule', ...) to reflect dynamic rule changes.
source to share