Binding ng-model to a Service parameter from inside a Template

205 Views Asked by At

I keep a data model in a service so that various controllers can use them. Inside the controller I scope it so that elements can bind to it using ng-model:

In the controller:

angular.module('hiveApp').controller('weatherController', function($scope, $rootScope, weatherModel, messageService, utilityService, $http, $timeout, $cookies, $window, $controller) {

$scope.weatherModel = weatherModel;

Then in the HTML element:

<input type="text" id="city" ng-model="weatherModel.city" />

So far so good, this works. The problem occurs when I bring a directive into the mix. I have a directive that handles a pair of radio buttons, and makes use of a template. That template attempts to use ng-model to reference that same weatherModel service parameters, however while it works from the HTML in the page itself, the directive template doesn't work:

app.directive('radiopair', function() {
return {
    restrict: 'E',
    template: `
        <div style="color:white; float:left">
            <input type="radio" id="metric" name="conversion" value="metric"
                   ng-model="weatherModel.conversion" selected> Metric<br>
            <input type="radio" id="imperial" name="conversion" value="imperial"
                   ng-model="weatherModel.conversion"> Imperial<br>
        </div>
    `,
    link: function ($scope, element, attrs) {
        element.on('click', function (event) {
            event.currentTarget.selected = true;
            $scope.refreshTable();  
        });
    }       
}
});

When I toggle between the two buttons, the ng-model=weatherModel.conversion value never gets updated. I figure this has got to be some scoping issue but I'm hitting a wall as to how to fix it.

1

There are 1 best solutions below

0
On

Instead of using a click handler to invoke the refreshTable function, use the ng-change directive:

app.directive('radiopair', function() {
    return {
        restrict: 'E',
        template: `
            <div style="color:white; float:left">
                <input type="radio" id="metric" name="conversion" value="metric"
                       ng-change="refreshTable()"
                       ng-model="weatherModel.conversion" selected> Metric<br>
                <input type="radio" id="imperial" name="conversion" value="imperial"
                       ng-change="refreshTable()"
                       ng-model="weatherModel.conversion"> Imperial<br>
            </div>
        `,
        //link: function ($scope, element, attrs) {
        //    element.on('click', function (event) {
        //        event.currentTarget.selected = true;
        //        $scope.refreshTable();  
        //    });
        //}       
    }
});

Avoid manipulating the select attribute of <input> elements. That should be done by the ng-model directive and the ngModelController.