我试图围绕AngularJS的工厂和服务,并继续陷入困境。这是一个基本的例子,类似于我试图解决的问题。
HTML
<div ng-controller="productGridController">
<div ng-repeat="category in categories" ng-controller="productCategoryController">
<input type="text" ng-model="category.name">
<div ng-repeat="product in products">
<input type="text" ng-model="product.name">
</div>
<a class="btn btn-small" ng-click="addProduct()">Add Product</a>
</div>
<a class="btn" ng-click="addCategory()">Add Category</a>
</div>
现在让我们说我想获得当前在根控制器productGridController
内实例化的所有产品的总数,并将其存储在我可以在{{1}内输出的变量中在诸如productGridController
由于每个$scope.totalProducts
都拥有自己的范围,我不确定如何进行全局计数器和总和呢?我认为服务或工厂可以做这样的事情,但我不确定如何实施它。
我尝试在productCategoryController
中添加根范围变量,如下所示:
productGridController
然后观看app.controller("productGridController", function($scope, $http, $rootScope, $timeout) {
$scope.totalProducts = 0;
$scope.categories = [];
$scope.addCategory = function() {
$scope.categories.push({name:''});
}
});
productCategoryController
当只添加了一个类别时,这种方法有效,但是当有多个类别时,它只会影响最近的类别。
另外请记住,在我的实际应用程序中,我需要从数据库中提取数据,因此这也需要能够实时工作,因此可以随时调用计数器功能以反映当前目前有多少产品的状态。
在Angular JS中最简单的方法是什么?
答案 0 :(得分:0)
首先:
您正在关注产品&#39;。当你打电话给&#39; products.push()&#39;在“添加产品”中,产品的价值不会发生变化;所以你的手表不会被调用。如果你反而说:
$scope.addProduct = function() {
$scope.products = $scope.products.concat([{name:''}]);
}
然后你的手表会按照你的预期被调用(因为那时产品的价值已经发生了变化)。
第二
不要忘记你也可以使用$ watch的功能形式:
$scope.$watch(function() {return $scope.products.length;}, function() {
$scope.totalProducts = $scope.products.length;
});
但主要是:为什么要使用$ watch?你可以说:
$scope.addProduct = function() {
$scope.products.push({name:''});
$scope.totalProducts = $scope.products.length;
}
因为你知道这是一种有副作用的行为。
使用服务的想法是更进一步,并将所有这些特定于数据的逻辑打包在一个我们不必考虑如何以及何时呈现的地方。然后,将该服务注入您的控制器,并且控制器公开相关的服务部分(通过范围)。
答案 1 :(得分:0)
当需要持久性或共享状态时,实施工厂或服务来管理该状态 - 这是关于差异的良好SO Q/A(以及提供者)。
$ watch很棒,但并不总是最好的选择。例如,如果您无法缓存产品数据集(可能是巨大的),那么通过$broadcast更改事件可能是更好的选择。
这是一个带有产品服务的plnkr demonstrating your scenario,用于广播添加/删除操作的事件,以及一个监听该更改事件并相应更新其内容的指令。
ProductService 的重要部分是在添加或删除产品时广播变更事件:
ModRewrite
在演示中,添加或删除产品时,服务方法 addProduct 和 removeProduct 会调用内部更改功能。
指令 productCount 会在产品计数更改通知时呈现当前产品计数和更新:
app.service('ProductService', function($rootScope) {
let self = {
PRODUCT_COUNT_DELTA: "PRODUCT_COUNT_DELTA",
$inject: ['$rootScope']
}
// broadcast a PRODUCT_COUNT_DELTA event with the latest product count.
function changes(changeType) {
if (changeType == 0)
$rootScope.$broadcast(self.PRODUCT_COUNT_DELTA, self.getProductCount());
}
同样,$ watch很方便,但并不总是正确的选择。