【问题标题】:Sharing model using service across controllers跨控制器使用服务共享模型
【发布时间】:2015-10-19 09:05:08
【问题描述】:

这里的学生开发者在 Angular 和更高级的 JavaScript 方面都超出了我的想象

我正在尝试增强一个基本的 Angular 应用程序,并且需要在控制器之间共享一个模型(这样我就可以在列表中选择一个项目(数组中的 JSON 对象)以显示来自同一对象的更多数据)。

服务:

(function() {
'use strict';

angular
    .module('App')
    .factory('companiesService', ['$http', 'ngAuthSettings', companiesService]); 


    function companiesService($http, ngAuthSettings) {

        var serviceBase = ngAuthSettings.apiServiceBaseUri;

        var Companies = function() {
                this.records = [];
                this.loading = false;
                this.params = {};
                this.params.filter = this.filter;
                this.params.offset = 0;
                this.params.max = 10;
        };

        Companies.prototype = {
            loadData : function() {
                if (this.loading || this.error || this.end) return;
                this.loading = true;

                $http({
                    method : 'POST',
                    url : serviceBase + 'company.php',
                    data : $.param(this.params), 
                    headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  // set the headers so angular passing info as form data (not request payload)
                }).then(function(response) {

                    for (var i = 0, len = response.data.records.length; i < len; i++) {
                        this.records.push(response.data.records[i]);
                    }
                    this.error = response.data.error; 
                    this.message = response.data.message;
                    this.params.offset = parseInt(response.data.offset) + this.params.max;
                    this.end = len < this.params.max; 
                    this.loading = false;
                }.bind(this));
            },
            getCompany : function(id) {
                var recs = this.records;
                if (recs) {
                    for (var i = 0, len = recs.length; i < len; i++) {
                        if (recs[i].id == id) {
                            return recs[i];
                        } else {
                            return -1;
                        }
                    }
                }
            }

        };
        return Companies;
    }
})();

控制器(用于列表视图)——这很好用

(function() {
    'use strict';
angular
    .module('App')
    .controller('companyController', ['$scope', 'companiesService', companyController]);

    function companyController($scope, companiesService) {
        $scope.companies = new companiesService();
    }

})();

第二个控制器如何访问相同的数据,即返回的“公司”的记录属性 - 或者更具体地说,我如何在第二个控制器内的这些记录上调用服务中的 getCompany 函数?

【问题讨论】:

  • 在我看来,您正在创建 Companies 类的特定实例。如果有多个并发用户,并且您使用服务通过服务创建类的多个实例。您是否有可能有多个用户(甚至是不同控制器下的同一用户)在假设他们正在处理具有相同继承的同一个对象时进行操作,而实际上它们是单独的对象,这可能会在以后给您带来问题?

标签: angularjs


【解决方案1】:

当您使用工厂时,当您在控制器中使用 new 关键字时,您正在创建 Companies 对象的新实例。如果您需要另一个控制器来访问这个新创建的公司,您有几个选择,但我相信最好的选择是创建一个服务,该服务创建一个 Companies 对象,您的两个控制器都可以通过注入访问该对象。例如:

.service('MyCompanies', function(companiesService){
    var state = {
        companies: new companiesService()
    };
    return {
        getState: function(){ return state; }
    };
});

然后您可以将MyCompanies 注入您的两个控制器并访问相同的公司实例:

$scope.state = MyCompanies.getState();
// now $scope.state.companies will be the same for any controller that calls the line above.

虽然它们都可以实现相同的目标,但我认为您应该将工厂视为创建事物的组件,而将服务视为持有其他组件可以与之交互的某种状态的组件。

【讨论】:

  • 谢谢!正是我想要的。
【解决方案2】:

我不明白你的代码。为此,你创建一个单一的:

function CompaniesService($http, ngAuthSettings) {
    .
    .
    .

    var companyCache = {};

    return {
            getCompany : function(id, callback) {
            var existInCache = companyCache[id];
            if(existInCache)
                callback(companyCache[id]);
            else{    
                $http({
                    method : 'POST',
                    url : serviceBase + 'company.php',
                    data : $.param(this.params), 
                    headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  // set the headers so angular passing info as form data (not request payload)
                }).then(function(response) {
                    companyCache[id] = response.data;
                    callback(companyCache[id]);
                });
            }
        }
    };
}

在控制器中传递为:

angular.module('App').controller('Controller1', ['$scope', 'CompaniesService']);
angular.module('App').controller('Controller2', ['$scope', 'CompaniesService']);
angular.module('App').controller('Controller3', ['$scope', 'CompaniesService']);

function Controller1($scope, CompaniesService) {
    $scope.companies = CompaniesService.getCompany(function(data){
        $scope.companies = data;
    });
}

function Controller2($scope, CompaniesService) {
    $scope.companies = CompaniesService.getCompany(function(data){
        $scope.companies = data;
    });
}

function Controller3($scope, CompaniesService) {
    $scope.companies = CompaniesService.getCompany(function(data){
        $scope.companies = data;
    });
}

【讨论】:

  • companyCache[id] = response.data; 不是response
  • 好吧,我修好了。谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-09-06
  • 2022-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多