Reputation: 2223
I have a directive rendering inputs based on a configuration sent by the server. Everything is working great except for the 'select' input. No matter what I try, the ng-model does not update. I have trimmed my code a lot to isolate the problem :
Javascript :
var myApp = angular.module('example', []);
myApp.factory('DynamicData', [function() {
return {
data: {
backup_frequency: 604800
}
};
}])
.directive('dynamicInput',
['$compile', 'DynamicData', function($compile, DynamicData) {
/**
* Render the input
*/
var render = function render() {
var input = angular.element('<select class="form-control" ng-model="inner.backup_frequency" ng-options="option.value as option.title for option in options"></select>');
return input;
};
var getInput = function ()
{
var input = render();
return input ? input[0].outerHTML : '';
};
var getTemplate = function(){
var template = '<div class="form-group">' +
'Select input ' +
'<div class="col-md-7">' + getInput() + '</div>' +
'</div>';
return template;
};
return {
restrict : 'E',
scope: {
content:'=content',
},
link : function(scope, element, attrs) {
var template = getTemplate();
scope.options = [
{title: "Daily", value: 86400},
{title: "Weekly", value: 604800},
{title: "Monthly", value: 2678400},
];
scope.inner = DynamicData.data;
console.info('inner data', scope.inner);
element.html(template);
element.replaceWith($compile(element.contents())(scope));
}
};
}])
.controller('FormCtrl', ['DynamicData', '$scope', function (DynamicData, $scope){
$scope.app = {};
$scope.save = function save() {
$scope.value = DynamicData.data.backup_frequency;
console.info('DynamicData', DynamicData.data);
};
}]);
HTML :
<head>
<script data-require="[email protected]" data-semver="1.3.8" src="https://code.angularjs.org/1.3.8/angular.js"></script>
<link href="style.css" rel="stylesheet" />
<script src="script.js"></script>
</head>
<body>
<h1>Dynamic Input :</h1>
<div data-ng-controller="FormCtrl">
<dynamic-input class="form-group" content="app"></dynamic-input>
<span data-ng-bind="value"></span><br/>
<button class="btn btn-primary" ng-click="save()">Save</button>
</div>
</body>
</html>
A working plunker is available : http://plnkr.co/edit/mNBTJzZXjX6mLyPz6NCI?p=preview
Do you have any ideas why the ng-model in the select is not updated ?
EDIT : What I want to achieve is updating the variable "inner.backup_frequency" (the reference to my data object returned by my factory DynamicData). As you can see in the plunker, whenever I change the option in the select, the variable contained in the ng-model is not updated.
Thank you for your time.
Upvotes: 9
Views: 3959
Reputation: 4570
I had a similar issue and find if you directly bind ng-model to a scope variable as below, the scope variable selection somehow will not be updated.
<select ng-model="selection" ng-options="option for option in options">
Instead, define a view model in your scope and bind ng-model to a field of view model the view model field will be updated.
<select ng-model="viewmodel.selection" ng-options="option for option in options">
In your controller, you should do this:
app.controller('SomeCtrl', ['$scope'
function($scope)
{
$scope.viewmodel = {};
});
Upvotes: 13
Reputation: 17064
I've fixed it. What you needed to do was not to replace the element's content with the compiled content, but rather replace it with the raw HTML and only then compile it.
element.html(template);
$compile(element.contents())(scope);
EDIT: I've edited your code to work without the directive:
EDIT 2: Also a version where it works with the directive, but without the compile:
Upvotes: 3