Something like a manual refresh is needed angularjs, and a $digest() iterations error -
(post edited again, new comments follow line)
i'm changing title of posting since misleading - trying fix symptom.
i unable figure out why code breaking $digest() iterations error. plunk of code worked fine. totally stuck, decided make code little more angular-like. 1 anti-pattern had implemented hide model behind controller adding getters/setters controller. tore out , instead put model $scope
since had read proper angular.
to surprise, $digest() iterations error went away. not know why , not have intestinal fortitude put old code , figure out. surmise involving controller in get/put of data added dependency under hood. not understand it.
edit #2 ends here.
(post edited, see edit below)
i working through first error: 10 $digest() iterations reached. aborting! error today.
i solved way:
<div ng-init="lineitems = ctrl.getlineitems()"> <tr ng-repeat="r in lineitems"> <td>{{r.text}}</td> <td>...</td> <td>{{r.price | currency}}</td> </tr </div>
now new issue has arisen - line items i'm producing can modified control on page. it's text box promo code. promo code adds discount lineitem array. show if ng-repeat
on ctrl.getlineitems()
.
since ng-repeat
looking @ static variable, not actual model, doesn't see real line items have changed , promotional discount doesn't displayed until refresh browser.
here's html promo code:
<input type="text" name="promo" ng-model="ctrl.promocode"/> <button ng-click="ctrl.applypromocode()">apply promo code</button>
the input
tag writing value model. bg-click
in button
invoking function apply code. change data behind lineitems.
i have been advised use $scope.apply(...)
. however, since applied matter of course ng-click
isn't going anything. indeed, if add ctrl.applypromocode()
, error since .apply()
in progress.
i'm @ loss.
edit
the issue above result of me fixing of symptom, not problem. here original html dying 10 $digest() iterations
error.
<table> <tr ng-repeat="r in ctrl.getlineitems()"> <td>{{r.text}}</td> <td>...</td> <td>{{r.price | currency}}</td> </tr> </table>
the ctrl.getlineitems()
function doesn't invoke model. decided keep model out of html as could.
this.getlineitems = function() { var total = 0; this.lineitems = []; this.lineitems.push({text:"your quilt "+sizes[this.size].block_size+" squares", price:sizes[this.size].price}); total = sizes[this.size].price; this.lineitems.push({text: threads[this.thread].narrative, price:threads[this.thread].price}); total = total + threads[this.thread].price; if (this.sashing) { this.lineitems.push({text:"add sashing", price: this.getsashingprice()}); total = total + sizes[this.size].sashing; } else { this.lineitems.push({text:"no sashing", price:0}); } if(isnan(this.promo)) { this.lineitems.push({text:"no promo code", price:0}); } else { this.lineitems.push({text:"promo code", price: promos[this.promo].price}); total = total + promos[this.promo].price; } this.lineitems.push({text:"shipping", price:this.shipping}); total = total + this.shipping; this.lineitems.push({text:"order total", price:total}); return this.lineitems; };
and model code assembled array of objects based upon items selected. i'll abbreviate class croaks long array has row.
function ordermodel() { this.lineitems = []; // result of lineitems call ... this.getlineitems = function() { var total = 0; this.lineitems = []; ... this.lineitems.push({text:"order total", price:total}); return this.lineitems; }; }
the problem each $digest
cycle, new array returned (even if contains objects equal values, new objects created).
to circumvent this, associate ngrepeat
lineitems
property , call getlineitems()
only when might have changed.
a possible implementation following:
<!-- view --> <table> <tr ng-repeat="r in ctrl.lineitems">...</tr> </table> /* controller */ .controller('myctrl', function (ordermodel) { this.ordermodel = ordermodel; this.lineitems = this.ordermodel.lineitems; this.reloaditems = this.ordermodel.getlineitems; // initialization this.reloaditems(); }); /* service */ app.service('ordermodel', function () { this.lineitems = []; this.getlineitems = function () { var total = 0; this.lineitems.splice(0, this.lineitems.length); ... (var = 0; < 10; i++) { total++; this.lineitems.push({text: 'order total', price: total}); } }; });
see, also, short demo.
Comments
Post a Comment