简体   繁体   English

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

[英]Sharing data between controllers, AngularJS

I'm facing the following situation in my Angular application and I would like to have some advices here. 我的Angular应用程序中遇到以下情况,我想在这里提出一些建议。

I have a page where I show some products, this page is managed by a controller called 'ProductsController'. 我有一个页面,其中显示了一些产品,该页面由名为“ ProductsController”的控制器管理。 This controller has a method called 'showProductDetails' which is called once the user clicks on a specific product, and the goal of this method is just to retrieve the details of the product and to display these details in a modal panel. 该控制器具有一种名为“ showProductDetails”的方法,一旦用户单击特定产品,即会调用该方法,该方法的目的只是检索产品的详细信息并在模式面板中显示这些详细信息。 Nothing really special until here. 直到这里,没有什么特别的。 The problem is that because of modularity I would like to attach a different controller to the modal panel, and to manage all the logic of this modal panel in the new controller, in this case 'ProductDetailController'. 问题是由于模块性,我想在模式面板上附加一个不同的控制器,并在新控制器(本例中为ProductDetailController)中管理该模式面板的所有逻辑。 The problem is that I retrieve the data of the product before opening the modal panel, but as I retrieve this data in the scope of the first controller, from the second controller I cannot access to the product that I have previously retrieved. 问题是我在打开模式面板之前先检索产品的数据,但是当我在第一个控制器的范围内检索此数据时,无法从第二个控制器访问以前检索的产品。 I've been told that to share data between controllers in angularJs is done through services, but I don't see how a stateless service can help me here. 有人告诉我,在angularJs中的控制器之间共享数据是通过服务完成的,但是我看不到无状态服务如何在这里为我提供帮助。

Here is my code to understand better the situation: 这是我的代码,可以更好地了解这种情况:

The first controller: 第一个控制器:

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();    
                               }]);

And the second controller: 第二个控制器:

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

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

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

So basically the question is how can access from the 'ProductDetailController' to the object 'selectedProduct' which is in the scope of the 'ProductsController'. 因此,基本的问题是如何从“ ProductDetailController”访问位于“ ProductsController”范围内的对象“ selectedProduct”。

Thank you for your help. 谢谢您的帮助。

Use resolve of the $modal to send your data to the new controller like below. 使用$ 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();    
                                      }]);

I dont know about the producfactory helper product query has a promise if it has a promise you can use like this.. 我不知道生产帮助器产品查询是否有承诺,如果有可以像这样使用的承诺。

$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})
        }
    });
};

And in the ProductDetailController you can inject this selectedProduct like below 在ProductDetailController中,您可以像下面这样注入这个selectedProduct。

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

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

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

This can indeed be done through services, since they are stateless and keep their data once instantiated. 实际上,这可以通过服务来完成,因为它们是无状态的,并且一旦实例化就保留其数据。

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);

You can then just inject productService in both controllers, load the products using productService.loadProducts() , and get them using productService.getProducts() . 然后,您可以只将productService注入两个控制器中,使用productService.loadProducts()加载产品,然后使用productService.getProducts()获取productService.getProducts()

This is just an example. 这只是一个例子。 Services can be used to share any kind of data. 服务可用于共享任何类型的数据。

Services are indeed the answer for you, or you can use pure eventing if you do not need to access the data more then once. 服务确实是您的答案,或者,如果您不需要访问数据一次以上,则可以使用纯事件。

Pure Eventing 纯事件

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
    });
});

Using a service. 使用服务。 The advantage of using a service is that the data is persisted. 使用服务的优势在于数据是持久的。

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);
    });
});

You could further enhance this were the service loaded the data and returns a promise in the getter. 您可以进一步增强此功能,即服务加载了数据并在getter中返回了promise。

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

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