subha
subha

Reputation: 1060

Fire ng-change when ng-model updated programmatically inside ng-repeat

I read topics related to this and found following, but still I am stuck.

How to $watch changes on models created by ng-repeat?

I am trying to implement plus, minus counter with following code. Now whenever ng-model updates either by clicking +/- button I want to fire ng-change. I understand that ng-change doesn't fire when the ng-model updated programatically. But the refrenced Stackoverflow has solution for that to add $watch on the ng-model. But its working if I create separate controller, not working inside current controller. ng-change is calling functions inside current controller. How to fix it??

<div class="input-group" ng-repeat="product in oc.itemdetail.lines">
    <input type="button" value="-" class="minus"
           ng-click="product.line.total = product.line.total - product.stepCount">

    <input  type="number"  ng-if="condition 1" ng-model="product.line.total" min="" max="" 
            step="product.stepCount" oninput="some condition"
            ng-change="oc.function1()" />
    <input  type="number"  ng-if="condition 2" ng-model="product.line.total" min="" max=""
            step="product.stepCount" oninput="some condition"
            ng-change="oc.function2()" />

    <input type="button" value="+" class="plus"
           ng-click="product.line.total = product.line.total + product.stepCount">

</div>

I have two input box above, based on ng-if condition either one will be shown at a time. Each ng-change is calling different function inside current controller. If I put separate controller then on click of +/- button following function is firing. But I want to call function inside ng-change

$scope.$watch('Count', function (oldValue, newValue) {
    if (newValue != oldValue)
      console.log(oldValue, newValue);
});

Upvotes: 1

Views: 1230

Answers (2)

georgeawg
georgeawg

Reputation: 48948

The code should avoid using the onchange attribute with the ng-model directive. The ng-if directive uses alot of resources. If the only reason it is being used is to switch the ng-change function, it should be avoided. The choice of ng-change function can be made in the controller.

<div class="input-group" ng-repeat="product in oc.itemdetail.lines">
    <input type="button" value="-" class="minus"
           ng-click="oc.decrement(product)">

    <input  type="number"  ng-model="product.line.total" min="" max="" 
            step="product.stepCount" ng-change="oc.update(product)" />

    <input type="button" value="+" class="plus"
           ng-click="oc.increment(product)">

</div>

Avoid complex formulations in templates. Instead put them in the controller:

oc.update = function(product) {
   if (oc.<condition 1>) {
     oc.function1();
   };
   if (oc.<condition 2>) {
     oc.function2();
   };
};

For performance reasons, avoid using watchers. Instead use the functions that change the model to invoke update operations:

oc.decrement = function(product) {
    product.line.total = product.line.total - product.stepCount;
    oc.update(product);
};

oc.increment = function(product) {
    product.line.total = product.line.total + product.stepCount;
    oc.update(product);
};

Putting complex expressions in the controller makes the code easier to understand, debug, test, and maintain.

Upvotes: 1

Harry Manoharan
Harry Manoharan

Reputation: 181

You can try by moving this 'Count = Count + s.increment' code on the ng-click event into a function in the JS file and in that function you can call ct.function2().

eg:-

   $ct.Counter = function(){
      Count = Count + s.increment;
       ct.function2();
   }

and call this method on ng-click

    ng-click="ct.Counter()"

Similarly you can implement the minus scenario.

Upvotes: 0

Related Questions