繁体   English   中英

在控制器之间共享数据,AngularJS

[英]Sharing data between controllers, AngularJS

我的Angular应用程序中遇到以下情况,我想在这里提出一些建议。

我有一个页面,其中显示了一些产品,该页面由名为“ ProductsController”的控制器管理。 该控制器具有一种名为“ showProductDetails”的方法,一旦用户单击特定产品,即会调用该方法,该方法的目的只是检索产品的详细信息并在模式面板中显示这些详细信息。 直到这里,没有什么特别的。 问题是由于模块性,我想在模式面板上附加一个不同的控制器,并在新控制器(本例中为ProductDetailController)中管理该模式面板的所有逻辑。 问题是我在打开模式面板之前先检索产品的数据,但是当我在第一个控制器的范围内检索此数据时,无法从第二个控制器访问以前检索的产品。 有人告诉我,在angularJs中的控制器之间共享数据是通过服务完成的,但是我看不到无状态服务如何在这里为我提供帮助。

这是我的代码,可以更好地了解这种情况:

第一个控制器:

app.controller('ProductsController', ['$scope','productsFactory','commonFactory','productsFactoryHelper','$filter','$modal',function ($scope,productsFactory,commonFactory,productsFactoryHelper,$filter,$modal)
                               {




$scope.showProductDetails = function (size,product) {

$scope.showLoader('Loading the details of the product. Please wait...');

productsFactoryHelper.Product.query({id:product.id},function(response)
    {
    $scope.selectedProduct=response;
    $scope.hideLoader();
    var modalInstance = $modal.open({
          templateUrl: 'productDetail.html',
          controller: 'ProductDetailController',
          size: size

        });
    },function(error)
    {
    commonFactory.Pop('error','This product is not available at this moment.  Please try again later. If the problem persists contact a system administrator');
                    $scope.hideLoader();
    });


};

_init();    
                               }]);

第二个控制器:

app.controller('ProductDetailController',['$scope','$modalInstance', function ($scope, $modalInstance) {

                                 $scope.ok = function () {
                                   $modalInstance.close();
                                 };

                                 $scope.cancel = function () {
                                   $modalInstance.dismiss('cancel');
                                 };
                               }]);

因此,基本的问题是如何从“ ProductDetailController”访问位于“ ProductsController”范围内的对象“ selectedProduct”。

谢谢您的帮助。

使用$ modal的resolve将数据发送到新的控制器,如下所示。

app.controller('ProductsController', ['$scope','productsFactory','commonFactory','productsFactoryHelper','$filter','$modal',function ($scope,productsFactory,commonFactory,productsFactoryHelper,$filter,$modal)
                                      {




    $scope.showProductDetails = function (size,product) {

        $scope.showLoader('Loading the details of the product. Please wait...');

        productsFactoryHelper.Product.query({id:product.id},function(response)
                {
            $scope.selectedProduct=response;
            $scope.hideLoader();
            var modalInstance = $modal.open({
                templateUrl: 'productDetail.html',
                controller: 'ProductDetailController',
                size: size,
                resolve:{
                    "selectedProduct":response
                }

            });
                },function(error)
                {
                    commonFactory.Pop('error','This product is not available at this moment.  Please try again later. If the problem persists contact a system administrator');
                    $scope.hideLoader();
                });


    };

    _init();    
                                      }]);

我不知道生产帮助器产品查询是否有承诺,如果有可以像这样使用的承诺。

$scope.showProductDetails = function (size,product) {

    $scope.showLoader('Loading the details of the product. Please wait...');

    var modalInstance = $modal.open({
        templateUrl: 'productDetail.html',
        controller: 'ProductDetailController',
        size: size,
        resolve:{
            "selectedProduct":productsFactoryHelper.Product.query({id:product.id})
        }
    });
};

在ProductDetailController中,您可以像下面这样注入这个selectedProduct。

app.controller('ProductDetailController',['$scope','$modalInstance','selectedProduct ' function ($scope, $modalInstance,selectedProduct ) {

    $scope.ok = function () {
        $modalInstance.close();
    };

    $scope.cancel = function () {
        $modalInstance.dismiss('cancel');
    };
}]);

实际上,这可以通过服务来完成,因为它们是无状态的,并且一旦实例化就保留其数据。

function productService($http) {

    this.products = [];

    this.loadProducts() {
        $http.get('/url/to/your/product/api').then(function(err, data) {    
            this.products = data.products;
        });
    };

    this.getProducts = function() {
        return this.products;
    }
}

angular
    .module('yourModule')
    .service('productService', productService);

然后,您可以只将productService注入两个控制器中,使用productService.loadProducts()加载产品,然后使用productService.getProducts()获取productService.getProducts()

这只是一个例子。 服务可用于共享任何类型的数据。

服务确实是您的答案,或者,如果您不需要访问数据一次以上,则可以使用纯事件。

纯事件

app.controller('parentCtrl', function($scope) {
    // Do something

    // Action completed
    @scope.$emit('someactionComplete', data);
});

app.controller('childCtrl', function($scope) {
    $scope.$on('someactionComplete', function(data) {
        // Process data
    });
});

使用服务。 使用服务的优势在于数据是持久的。

app.controller('parentCtrl', function($scope, MyService) {
    // Do something

    // Action completed
    MyService.setData(data);
    @scope.$emit('someactionComplete');
});

app.controller('childCtrl', function($scope) {
    $scope.$on('someactionComplete', function() {
        MyService.getData(data);
    });
});

您可以进一步增强此功能,即服务加载了数据并在getter中返回了promise。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM