Angularjs 绑定到控制器作用域上的服务属性

Angularjs 绑定到控制器作用域上的服务属性,angularjs,Angularjs,我一直在尝试在控制器中使用服务,特别是将控制器上的作用域属性绑定到服务中的属性 在下面的代码中,我发现控制器中的$scope.stockCountProp与$scope.stockCountFunc属性不同,后者不会正确递增 我发现一些帖子建议您应该使用作用域函数绑定到服务属性,为什么直接属性绑定方法不起作用 <div ng-app="myApp" ng-controller="StockCtrl"> <h2>Stock Checker</h2>

我一直在尝试在控制器中使用服务,特别是将控制器上的作用域属性绑定到服务中的属性

在下面的代码中,我发现控制器中的$scope.stockCountProp与$scope.stockCountFunc属性不同,后者不会正确递增

我发现一些帖子建议您应该使用作用域函数绑定到服务属性,为什么直接属性绑定方法不起作用

    <div ng-app="myApp" ng-controller="StockCtrl">
    <h2>Stock Checker</h2>
    <h3>Using a scoped function binding</h3>
    Current Stock Level: {{stockCountFunc()}} 
    <br>
    <h3>Using a direct property binding</h3>
    Current Stock Level: {{stockCountProp}} 
    <br><button ng-click="updateStock()">Update Stock</button>
</div>

<script>
var app = angular.module('myApp', [])
.service('StockService', function() {
    var StockModel = {};
    StockModel.totalCount = 5;

    StockModel.addStockItem = function() {
        //Some API call here to add a stock item...
        StockModel.totalCount++;
    };

    StockModel.getTotalCount = function () {
        return StockModel.totalCount;
    };

    return StockModel;
 })
.controller('StockCtrl', function($scope, StockService) {
    $scope.stockCountFunc = StockService.getTotalCount;
    $scope.stockCountProp = StockService.totalCount;


    $scope.updateStock = function() {
        StockService.addStockItem();
    };
});
</script>

验货员
使用作用域函数绑定
当前库存水平:{{stockCountFunc()}}

使用直接属性绑定 当前库存水平:{{stockCountProp}
更新库存 var app=angular.module('myApp',[]) .service('StockService',function(){ var-StockModel={}; StockModel.totalCount=5; StockModel.addStockItem=函数(){ //此处的一些API调用用于添加库存项。。。 StockModel.totalCount++; }; StockModel.getTotalCount=函数(){ 返回StockModel.totalCount; }; 收益模型; }) .controller('StockCtrl',函数($scope,StockService){ $scope.stockCountFunc=StockService.getTotalCount; $scope.stockCountProp=StockService.totalCount; $scope.updateStock=function(){ StockService.addStockItem(); }; });
演示小提琴

控制器中的这一行执行一次,它是声明。在第一种情况下,您绑定的是函数而不是值。函数永远不会改变,值也不会改变。 在第二个例子中,您将服务的值分配给控制器。它永远不会改变

Current Stock Level: {{stockCountFunc()}} 
当您调用此函数时,无论值是多少,我们将始终调用工厂中的getter。这意味着如果值更改,getter将返回新值

Current Stock Level: {{stockCountProp}} 
这个函数将调用控制器的值,因为它是一个值而不是一个函数。它将简单地返回初始值


因此,当它为值时,Angular将不进行绑定。这将是一种矫揉造作的行为。

如果服务中的属性是原始属性(在您的例子中是int),那么将其分配给控制器中的$scope将生成一个副本而不是引用。因此,更新服务属性无效,因为没有对控制器副本进行更改

您提到的函数可以工作,因为每次调用它时,您都会从服务中获取当前值


作为一种替代方法,如果您希望避免使用函数,您可以从包含该值的服务返回一个对象,例如
{myTotal:123}

如果您希望在这两个对象中都发生更改,则应使用更新控制器和服务中的值

为了使
totalCount
绑定按照原型继承工作,我们应该使用object&然后应该在对象中添加
totalCount

标记

{{model.totalCount}}
服务

.service('StockService', function() {
    var StockModel = {};
    StockModel.model = {}; //change structure to object
    StockModel.model.totalCount = 5;

    StockModel.addStockItem = function() {
        //Some API call here to add a stock item...
        StockModel.model.totalCount++;
    };

    StockModel.getTotalCount = function () {
        return StockModel.model.totalCount;
    };

    return StockModel;
})
控制器

.controller('StockCtrl', function($scope, StockService) {
    $scope.stockCountFunc = StockService.getTotalCount;
    $scope.stockCountProp = StockService.totalCount;

    //this will provide you the two way binding thing as you are using dot rule
    $scope.model = StockService.model;

    $scope.updateStock = function() {
        StockService.addStockItem();
    };
});

谢谢Pierre,那么在绑定到stockCountFunc()的情况下,Angular如何知道何时重新计算,换句话说,它何时知道服务上的totalCount属性已更改?我对观察者的角色略知一二,这里是不是在函数绑定中使用了观察者?是DOM完成了这项工作。观察者将一直重新评估DOM。这不仅仅是当你的服务改变的时候。有时,重新评估没有任何作用,因为没有任何变化。
.controller('StockCtrl', function($scope, StockService) {
    $scope.stockCountFunc = StockService.getTotalCount;
    $scope.stockCountProp = StockService.totalCount;

    //this will provide you the two way binding thing as you are using dot rule
    $scope.model = StockService.model;

    $scope.updateStock = function() {
        StockService.addStockItem();
    };
});