Angularjs $rootScope.$apply()忽略变量赋值

Angularjs $rootScope.$apply()忽略变量赋值,angularjs,Angularjs,在我的服务中,我有以下代码: setInterval(function () { $rootScope.$apply(function () { cart.push({ "Id": 4, "Name": "Some item", "Price": 4 }); }); }, 3000); 工作示例: 这是正确的:将购物车更改推送到视图中 但是,当我向购物车分配新

在我的服务中,我有以下代码:

setInterval(function () {
    $rootScope.$apply(function () {
        cart.push({
            "Id": 4,
                "Name": "Some item",
                "Price": 4
        });
    });
}, 3000);
工作示例:

这是正确的:将购物车更改推送到视图中

但是,当我向购物车分配新值时,更改不会推送到视图:

setInterval(function () {
    $rootScope.$apply(function () {
        var newcart = [{
            "Id": 4,
                "Name": "Some item " + Math.random(),
                "Price": 4
        }];

        cart = newcart;
    });
}, 3000);
例如:

  • 这是什么原因
  • 解决此问题的最佳/最优雅的解决方案是什么
编辑

这是我根据以下答案构建的有效解决方案:
jsfiddle.net/ko8edf32/11

您必须在$scope上使用对象

$scope.model = { cart: [] };
以下是一个工作示例:


这里有一个解释:

我已经将您的购物车更改为更具“角度”的方式,带有双向数据绑定。我添加了第二个控制器,向您展示了它在没有
getter/setters
的情况下,以及通常带有一点
magic


数组是一个对象,而不是一个基本类型。另外,您的提琴在更改后可能未保存,因为它与我的第二个提琴相同。谢谢,您更新的提琴似乎确实工作正常,但我认为您的解释不完全正确。@Thomastock我编辑了我的答案并添加了一个新链接,我希望它能帮助你找到答案。我还是不喜欢这个答案。控制器现在依赖于服务变量的命名。当我在控制器中将“model.cart”更改为“model.mycart”(而不是在服务中)时,您的小提琴不再工作。您好@Thomas Stock,我看到您正在使用factory,然后您将cart保存在rootScope上,出于您的目的,最好将数据存储到工厂/服务中,并以双向数据绑定的方式将其与控制器很好地连接起来,而不是使用apply@maurycy字体你能更新我的小提琴吗?我是AngularJS的新手,不太明白你的意思。我使用rootScope是因为我在试验,老实说,我还没有完全理解它的作用这是因为
ng repeat
创建了新的子作用域。这就是为什么您不能再显式地跟踪或消化这个范围。所以最好清除购物车而不是创建新购物车。这与在工厂中使用局部变量和在控制器中使用不同名称的范围变量有关。这是第二个小提琴以同样的方式改变,我想修复。我将用这个简化来更新我的问题,嗯,好的,所以基本上您直接在视图中引用服务变量。我已经用这个推理更新了我的示例,它确实起作用了:我将调查这是否解决了我实际实现中的问题(显然我的小提琴是一个简化版本),然后报告。嘿,谢谢你的帮助。我已经做了进一步的调查,当将一个项目从一个ng重复列表传递到另一个时,似乎出现了问题。我希望我能更详细一些,但恐怕我已经花了太多时间在这上面了。我会将你的答案标记为已接受,因为它是最完整的,但我更喜欢在上面的评论中使用小提琴,因为它更接近我的原始示例。
homeApp.factory("cartService", function($rootScope) {
  var service = null
  service = {
    all: function() {
      return service.cart;
    },
    add: function(item) {
      service.total += item.Price
      service.cart.push(item);
    },
    remove: function(item) {
      service.total -= item.Price
      service.cart.splice(service.cart.indexOf(item), 1);
    },
    cartUpdated: function(newValue) {
      service.cart = newValue;
    },
    cart: [],
    total: 0
  }
  return service;
});