Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ngModel not updating in select

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.

like image 808
Alexandre Nucera Avatar asked Feb 13 '15 12:02

Alexandre Nucera


1 Answers

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 = {};
    });
like image 96
Yang Zhang Avatar answered Oct 13 '22 05:10

Yang Zhang