$watch() 没有更新 $scope
$watch() isn't updating the $scope
我有以下控制器,当我调用 $scope.remove()
时,它向 usercart 发出请求,后者向 api 发出请求。 api returns 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>
此外,当页面加载时 table 显示正常。就在我运行删除函数的时候。
我没试过,但我相信这是问题所在
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
观察本地 $scope
以获取您在单例 usercart
中更改的值绝对行不通,除非您明确地传递了该本地范围。我们可以通过删除 $watch
并解决我们可以从我们的服务中 return 的承诺来简化这一点。这允许通用重用并减少观察者污染我们的控制器。观察以下变化...
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;
});
};
});
我有以下控制器,当我调用 $scope.remove()
时,它向 usercart 发出请求,后者向 api 发出请求。 api returns 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>
此外,当页面加载时 table 显示正常。就在我运行删除函数的时候。
我没试过,但我相信这是问题所在
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
观察本地 $scope
以获取您在单例 usercart
中更改的值绝对行不通,除非您明确地传递了该本地范围。我们可以通过删除 $watch
并解决我们可以从我们的服务中 return 的承诺来简化这一点。这允许通用重用并减少观察者污染我们的控制器。观察以下变化...
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;
});
};
});