如何正确绑定到AngularJS中的服务属性?

时间:2015-12-11 17:21:52

标签: javascript angularjs data-binding object-literal

我有一个工厂,我有几个预定义的合作伙伴(可能是其他任何东西,我认为这是一个容易理解的例子)。在运行时,我们选择当前的伙伴(基于我在此省略的一些逻辑)。

angular.module('myApp').factory('PartnersService', function ($location, $log) {

  var partners = {
    firstPartner: {
      name: 'Default Partner',
      id: 1 // just an extra property as example 
    },
    secondPartner: {
      name: 'Other Partner',
      id: 2
    }
  };

  // set default value
  var partner = partners.firstPartner;

  var initPartner = function () {
    // based on some logic (omitted), select partner
    partner = partners.secondPartner;
    $log.log("initPartner should have changed partner to " +  partner.name);
  };

  return {
    initPartner: initPartner,
    partners: partners,
    partner: partner,
  };
});

然后,我想以PartnersService.partner的身份访问该合作伙伴并查看其更改,例如来自控制器:

angular.module('myApp').controller('myController',
  function ($scope, $log, PartnersService) {
    // PartnersService.partner is the default partner (firstPartner)
    PartnersService.initPartner();
    // After initPartner, PartnersService.partner is still
    // the default, but I expected it to change
});

我找到了一些解决方法(在我看来...... 是他们的解决方法吗?),但对我来说感觉不自然,所以我想问一下是否有&#39 ;更好的方式。

JS Bin上查看我的完整工作示例。如果你觉得这个例子有点冗长,我很抱歉,但我想确保Stack Overflow用户理解我的担忧,并指出我的想法是否有问题。

解决方法1(getter?):

angular.module('myApp').controller('myController', function ($scope, $log, PartnersService) {
  PartnersService.initPartner();
  var partner = PartnersService.getPartner();
  $log.log('I could use a getter: ' + partner.name);
});

angular.module('myApp').factory('PartnersService', function ($location, $log) {

  var getPartner = function () {
    return partner;
  };

  return {
    getPartner: getPartner,
    // ...
  };
});

解决方法2(嵌套在对象文字中):

angular.module('myApp').controller('myController', function ($scope, $log, PartnersService) {
  PartnersService.initPartner();
  $log.log('or nest the partner in an extra object literal: '
     + PartnersService.extraObjectLiteral.partner.name);
});

angular.module('myApp').factory('PartnersService', function ($location, $log) {
  var partners = { /*...*/ }
  var extraObjectLiteral = {
    partner: partners.firstPartner
  };

  var initPartner = function () {
    // based on some logic (omitted), select partner
    extraObjectLiteral.partner = partners.secondPartner;
  };

  return {
    extraObjectLiteral: extraObjectLiteral,
    //...
  };
});

3 个答案:

答案 0 :(得分:1)

更改为:

this.partner = partners.secondPartner;
在initPartner方法中

。这将解决它。

当你做

时你真正在做什么
  var partners = { ... }
  var partner = partners.firstPartner;

是,您在类中创建本地对象,但它们不是该类的公开成员。

  return {
    initPartner: initPartner,
    partners: partners,
    partner: partner
  };

创建类的成员,并将局部变量的值复制到类的成员。在initPartner方法中,您更改了本地对象,但类的对象保持不变。

答案 1 :(得分:1)

我会选择使用getter和setter的方法,因为它遵循Revealing Module Pattern,这是维护更清晰,更易读和易懂的代码的首选。

工厂代码如下。

(function () {
    angular.module('myApp').
        factory('PartnersService', PartnersService);

    function PartnersService($location, $log) {
        var partners = {
            firstPartner: {
                name: 'Default Partner',
                id: 1 // just an extra property as example 
            },
            secondPartner: {
                name: 'Other Partner',
                id: 2
            }
        };
        var partner;

        //Set default value
        setDefaultPartner();

        var service = {
            getPartner: getPartner,
            setPartner: setPartner
        };
        return service;

        /*** Function Declarations ***/

        /* Accessible Functions */

        function getPartner() {
            return partner;
        }

        function setPartner() {
            var selectedPartner = initPartner();

            return selectedPartner;
        }

        /* Private Functions */

        function initPartner() {
            /*
             * Some (omitted) logic to select partner
             */

             partner = partners.secondPartner;
             $log.log("initPartner should have changed partner to " +  partner.name);

             return partner;
        }

        function setDefaultPartner() {
            partner = partners.firstPartner;
        }
    }
})();

请注意,唯一公开/可访问的成员是getPartnersetPartner(调用initPartner)函数。

控制器如下。

(function () {
    angular.module('myApp').
        controller('myController', myController);

    function myController($scope, $log, PartnersService) {
        $scope.partner = PartnersService.getPartner();
        $log.log("should be default partner: " + $scope.partner.name);

        $scope.partner = PartnersService.setPartner();
        $log.log("After setPartner which calls initPartner, the current partner is now the " + $scope.partner.name);
    }
})();

修改JS Bin,以下是生成的控制台日志。

"should be default partner: Default Partner"
"initPartner should have changed partner to Other Partner"
"After setPartner which calls initPartner, the current partner is now the Other Partner"

答案 2 :(得分:0)

我认为你没有遗漏任何明显的东西。你的两个解决方案似乎都没问题,除了在后一种情况下我可能会使用以下结构:

var partners = { ... };

var initPartner = function () {
    retObj.partner = partners.secondPartner;
};

var retObj = {
    initPartner: initPartner,
    partners: partners,
    partner: partners.firstPartner
};   

return retObj;