【问题标题】:$watch() isn't updating the $scope$watch() 没有更新 $scope
【发布时间】:2015-12-11 22:05:41
【问题描述】:

我有以下控制器,当我调用$scope.remove() 时,它向用户购物车发出请求,用户购物车向 API 发出请求。该 api 返回 json 对象,该对象具有一个带有购物车项目数组的对象。

页面上的 html 使用 ng-repeat 循环遍历项目,但由于某种原因页面没有更新,我不知道为什么。

// Main controller
app.controller('Checkout', function($scope, usercart){

    $scope.cart = [];

    $scope.$watch(function(){
        return usercart.cart;
    }, function(newVal, oldVal){
        if(newVal !== oldVal){
            $scope.cart = newVal;
        }
    }, true);

    $scope.remove = function(domain){
        usercart.remove(domain);
    };

});

此服务向 api 发出请求并保存购物车数据。

// User cart service
app.service('usercart', function(cart){
    this.remove = function(domain){
        // cart is an api service to make http requests
        cart.removeDomain(domain).success(function(data){
            this.cart = data.cart;
        });
    };
});

这是一个 json 响应示例:

{
    "message":"Success",
    "cart":[{
        "domain":"asdfsadfsadf.org",
        "years":2,
        "amount":9
    },{
        "domain":"asdsmembers.cc",
        "years":2,
        "amount":24.95
    },{
        "domain":"asdsmembers.tv",
        "years":2,
        "amount":39.95
    }]
}

这里是html:

<tr ng-repeat="i in cart">
    <td data-th="Product">
        {{i.domain}}
    </td>
    <td data-th="Price">${{i.amount|number:2}}</td>
    <td data-th="Quantity">
        <select ng-model="i.years" ng-options="y.value as y.name for y in selYears" ng-disable="isInCart(i.domain)" ng-class="{disabled: isInCart(i.domain)}" ng-change="update(i.domain, 'years', i.years)"></select>
    </td>
    <td class="actions" data-th="" align="center">
        <button class="btn btn-default btn-sm" style="background: #333;" ng-click="remove(i.domain)"><span class="glyphicon glyphicon-remove-circle" aria-hidden="true" style="color:#fff;"></span></button>
    </td>
    <td data-th="Subtotal" class="text-center">${{i.years * i.amount|number:2}}</td>
</tr>

当页面加载时,表格也显示正常。就在我运行删除功能时。

【问题讨论】:

  • 你能告诉我们你的模型/模板(HTML)吗?
  • 好的,我已经添加了 HTML
  • 只是对您的 html 的评论。您可以将&lt;td data-th="Price"&gt;${{i.amount|number:2}}&lt;/td&gt; 更改为&lt;td data-th="Price"&gt;{{i.amount|currency}}&lt;/td&gt;
  • 您的控制台是否出现任何错误?
  • 不,没有错误

标签: javascript html angularjs angularjs-service


【解决方案1】:

我没试过,但我相信问题出在这里

cart.removeDomain(domain).success(function(data){
        this.cart = data.cart;
    });

由于this 是指向回调函数调用者的指针,您将在cart api 服务上创建cart 属性。为了规避这个问题,您应该创建一个名为(按照约定)self 的变量并将this 分配给它(在usercart 服务的开头):

var self = this;

之后,将您的代码更改为:

cart.removeDomain(domain).success(function(data){
        self.cart = data.cart;
    });

为了更好地理解你可以通过这个post

【讨论】:

  • 啊,是的,没错。我使用了$this = this 并对其进行了更新,它可以正常工作。
【解决方案2】:

查看本地 $scope 以获取您在单例 usercart 中更改的值肯定是行不通的,除非您明确地传入该本地范围。我们可以通过删除$watch 并解决我们可以从我们的服务返回的承诺来简化这一点。这允许通用重用并减轻观察者污染我们的控制器。观察以下变化...

app.service('usercart', function(cart) {
    this.remove = function(domain) {
        return cart.removeDomain(domain) // return promise
    };
});

app.controller('Checkout', function($scope, usercart) {
    $scope.remove = function(domain) {
        usercart.remove(domain).then(function(data) { // resolve promise
            $scope.cart = data.cart;
        });
    };
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-05
    • 2013-06-25
    • 2014-08-22
    • 1970-01-01
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    相关资源
    最近更新 更多