【问题标题】:Something like a manual refresh is needed angularjs, and a $digest() iterations errorangularjs 需要手动刷新之类的东西,并且 $digest() 迭代错误
【发布时间】:2014-07-30 14:14:12
【问题描述】:

(再次编辑帖子,新的 cmets 遵循此行)

我正在更改此帖子的标题,因为它具有误导性 - 我试图修复一个症状。

我无法弄清楚为什么代码会因 $digest() 迭代 错误而中断。我的一段代码运行良好。我完全被困住了,所以我决定让我的代码更像 Angular。我实现的一种反模式是通过向控制器添加 getter/setter 将模型隐藏在控制器后面。我把所有这些都撕掉了,而是把模型放到了$scope,因为我读过那是正确的 Angular。

令我惊讶的是,$digest() 迭代 错误消失了。我不知道为什么,也没有勇气将旧代码放回去并弄清楚。我推测,通过让控制器参与数据的获取/放置,我在后台添加了一个依赖项。没看懂。

编辑 #2 到此结束。

(已编辑,请参阅下面的编辑)

我正在处理我的第一个 错误:达到 10 个 $digest() 迭代。中止! 今天出错了。

我是这样解决的:

<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>

现在出现了一个新问题 - 我正在生成的订单项可以通过页面上的另一个控件进行修改。这是促销代码的文本框。促销代码向 lineItem 数组添加折扣。如果我可以ng-repeat 超过ctrl.getLineItems(),它就会出现。

由于ng-repeat 查看的是静态变量,而不是实际模型,因此它看不到实际订单项已更改,因此在我刷新浏览器之前不会显示促销折扣。

这是促销代码的 HTML:

<input type="text" name="promo" ng-model="ctrl.promoCode"/>
<button ng-click="ctrl.applyPromoCode()">apply promo code</button>

input 标签正在将值写入模型。 button 中的 bg-click 正在调用将应用代码的函数。这可能会更改 lineItems 后面的数据。

有人建议我使用$scope.apply(...)。但是,由于ng-click 理所当然地应用了它,所以它不会做任何事情。事实上,如果我将它添加到 ctrl.applyPromoCode(),我会收到一个错误,因为 .apply() 已经在进行中。

我很茫然。

编辑

上面的问题可能是我修复症状的结果,不是问题。这是因 10 $digest() iterations 错误而死的原始 HTML。

<table>
    <tr ng-repeat="r in ctrl.getLineItems()">
        <td>{{r.text}}</td>
        <td>...</td>
        <td>{{r.price | currency}}</td>
    </tr>
</table>

ctrl.getLineItems() 函数做的不多,只是调用了一个模型。我决定尽可能将模型排除在 HTML 之外。

this.getLineItems = function() {
    var total = 0;
    this.lineItems = [];


    this.lineItems.push({text:"Your quilt will be "+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;

};

模型代码根据所选项目组装了一组对象。只要数组有一行,我就会缩写这个类。

function OrderModel() {
    this.lineItems = []; // Result of the lineItems call
    ...
    this.getLineItems = function() {
    var total = 0;
    this.lineItems = [];
        ...
        this.lineItems.push({text:"Order Total", price:total});
    return this.lineItems;
    };
}

【问题讨论】:

  • 我以为这就是$apply() 的用途。
  • 你试过了吗?
  • 现在正在处理它。到目前为止没有太多的运气。我需要了解有关“$scope”的更多信息。
  • 发现一个帖子证实了我的建议:How can I tell AngularJS to “refresh”
  • 应用在这里帮不了你。问题是您遇到了问题,而不是解决问题,您只是更改了应用程序的语义。现在您的应用程序无法运行(例如,更新 ngRepeat 中的项目)。最好是解决原来的问题。显示一些代码(产生错误的原始代码)。

标签: angularjs


【解决方案1】:

问题在于,每个$digest 循环都会返回一个新数组(即使它包含具有相等值的对象,也会创建新对象)。

为了避免这种情况,您可以将ngRepeatlineItems 属性相关联,并在可能发生变化时调用getLineItems()


可能的实现如下:

<!-- The VIEW -->
<table>
    <tr ng-repeat="r in ctrl.lineItems">...</tr>
</table>

/* The CONTROLLER */
.controller('myCtrl', function (OrderModel) {
    this.orderModel  = OrderModel;
    this.lineItems   = this.orderModel.lineItems;
    this.reloadItems = this.orderModel.getLineItems;

    // Initialization
    this.reloadItems();
});

/* The SERVICE */
app.service('OrderModel', function () {
    this.lineItems = [];
    this.getLineItems = function () {
        var total = 0;
        this.lineItems.splice(0, this.lineItems.length);
        ...
        for (var i = 0; i < 10; i++) {
            total++;
            this.lineItems.push({text: 'Order Total', price: total});
        }
    };
});

另请参阅此short demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 2014-03-20
    • 2017-10-28
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多