1

I don't understand this, but I suspect I'm doing something wrong, or a non-angularjs way.

I have a checkbox list inside ng-repeat. It controller loads the list from a JSON. Pretty straightforward really. I'm then using a directive (car-select) on each of the resulting checkboxes. This directive calls a function inside the main $scope (selectBrand()). This cycles through the selected checkboxes, and if checked==true, add to $scope.brand. I've added a textbox so that $scope.brand fills it, and i've set it to required so that it fires the built in validation e.g:

HTML:

<div ng-repeat="v in viewModel">
  <label class="checkbox">
    <input type="checkbox" ng-model="v.c" ng-checked="v.c" />{{v.n}}
  </label>
</div>
<input type="text" name="brands" ng-model="brands" car-select required/> <br>

JS:

  $scope.selectBrand = function() {
    var selectedBrands = [];
    angular.forEach($scope.viewModel, function(v){ 
      if (v.c)
        selectedBrands.push(v.v);
    })
    if (selectedBrands.length > 0)
      $scope.brands = selectedBrands;
    else
      $scope.brands = null;
  }

DIRECTIVE:

app.directive('carSelect', function() {
  return function(scope, element) {
    element.bind('change', function() {
      scope.selectBrand();
    })
  }
});

Here's the weird part which I don't understand. It took a while to figure out that this particular line was making this whole thing work. If I add the following in the page, everything works great. But if i remove it, the whole thing breaks. WHY?!

<div>{{selectBrand()}}</div>

It's like the whole thing doesn't bind unless the above is called in the HTML. It's called in the directive, and I've tried putting that call inside the clickButton() function, but eventually it breaks. Either way, the live update of the textbox seems to fail if the above is removed. I'd love to get a good explanation of how I'm doing something wrong and how I could fix it :)

PLUNKER: http://plnkr.co/edit/4QISKcq7YYH678YLsTTF?p=preview

2
  • can you pass your plunker to public, to do update. Commented May 6, 2013 at 8:01
  • 1
    The typical way to update it if you're not the author is to "Fork" it. Then link back the new URL for your updated version of the plunk. Commented May 6, 2013 at 8:03

1 Answer 1

2

Ok, i create fork ;-)

update variable with only data checked

your model :

{"cars":
  [
    {"v":"m","n":"Mini","c":false},
    {"v":"c","n":"Corvette","c":true},
    {"v":"b","n":"BMW","c":true},
    {"v":"l","n":"Lamborghini","c":true},
    {"v":"f","n":"Ferrari","c":false}
  ]
}

you want only checked :

$scope.brands = $filter('filter')($scope.viewModel, {c: true});

when model change you want to update your variable so use watch in controller

$scope.$watch('viewModel', function(newval, oldval){
                        if (oldval != newval)
                        {   
                      $scope.brands = $filter('filter')($scope.viewModel, {c: true});
                            }
                            },true
                        );
  });

see http://plnkr.co/edit/PnABre?p=preview

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your response. Interesting, i thought $watch was generally bad practice. But i guess having the function in the html is almost like a $watch because it's constantly fired. Anyways, here's a more polished plunk using the above technique. plnkr.co/edit/hLD9zA?p=preview
$watch is fire when you change scope.model only. you can add a breakpoint in your watch function to analyse the comportment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.