从服务传递值

Passing values from a service

本文关键字:服务      更新时间:2023-09-26
  1. 我是否需要创建一个getCurrent来保留绑定(如果我的视图ex中有{{current.status}}(?还是current: current就足够了?

  2. 如果我做$scope.status = services.status,我会释放到status的绑定吗。这意味着status在视图中更改后将不会更新。

  3. 会保留到someValue的绑定吗?这意味着如果我进行$scope.someValue = services.someValue ,它在服务中发生了变化,那么它在我的视图中就会发生变化

    function someService() {
    var current = {
        status: ''
    };
    var someValue = 'hello';
    //////////
    var service = {
        current: current,
        getCurrent: getCurrent,
        status: current.status,
        someValue: someValue
    };
    return service;
    //////////
    function getCurrent() {
        return current;
    }
    }
    
  1. 不,您不需要getCurrent方法,current:current应该足够了

2&3.不,因为您正在将作用域变量设置为服务的属性($scope.status=service.status(,并且这些属性是字符串,所以不会保留绑定。但是,如果您将整个服务对象指定为作用域变量,并在绑定中使用句点表示法,则它们会这样做,因为您将更新其引用已注入控制器(服务(的对象。需要注意的重要事项是为了理解为什么你的方法不起作用,但另一种选择是理解

  • 对象是通过引用传递的
  • 出于上述原因,angular建议您的绑定始终使用句点表示法

这就是你的代码使其工作的样子:

//service
.factory('service', function() {
    var current = {
      status: 'theStatus'
    };
    var someValue = 'hello';
    var service = {
        current: current,
        status: current.status,
        someValue: someValue
    };
    return service;
  })
// controller
.controller('theCtrl', ['$scope', 'service', function($scope, service) {
  $scope.serviceData = service;
}])
// view
<p>{{serviceData.current}}</p>
<p>{{serviceData.status}}</p>
<p>{{serviceData.someValue }}</p>

下面是示例plunker:http://plnkr.co/edit/n2P07mjwnMVHCl4l7SAj?p=preview。请注意,它有两个示例,第一个示例显示您的方法,第二个示例显示对象方法。

编辑-大警告:

需要注意的一个重要警告是,在您的服务中,如果someValuecurrent变量发生更改,您的视图将不会更新。因为我们正在返回服务对象,所以更改将反映在服务对象的someValuecurrentstatus属性中,但这些更改不会导致原始currentsomeValue变量也同步。

好吧,由于您使用JavaScript编程,您不必像在Java中那样使用getter/setter。

所有angular服务都是singleton,因此您可以轻松地共享一些数据。此外,通过创建Factory,您将能够返回对象并在其中包含所需内容,例如方法,该方法将被调用。您可以与工厂模式建立连接。

在您的情况下,您可以将服务实例保存到当前的$scope中。

编辑

在您的工厂中,您应该返回current对象。然后,您应该在视图中使用它来检索当前状态。因此,您将得到一个对象,而不仅仅是一个固定值,因此它将更新。

控制器

(function(){
function Controller($scope, Service) {
  //Register the Service instance into our scope
  $scope.service = Service;
  //Retrieve current object with status property
  $scope.working = Service.current;
  //Retrieve VALUE of current object
  $scope.not_working = Service.status;
  $scope.changeStatus = function() {
    Service.changeStatus('another status');
  }
}
angular
.module('app', [])
.controller('ctrl', Controller);
})();

服务

(function(){
  function Service($timeout) {
    var current = {
      status: 'off'
    };
    var someValue = 'hello';
    $timeout(function() {
      //Update service status
      current.status = 'on';
    }, 500);
    //////////
    var service = {
      //Return the current object
      current: current,
      //Just set the VALUE of current.status
      status: current.status,
      getCurrent: getCurrent,
      someValue: someValue,
      changeStatus: changeStatus
    };
    return service;
    function getCurrent() {
      return current;
    }
    function changeStatus(status) {
      alert("status changed");
      //Modifying status property of current object
      current.status = status;
    }
  }
  angular
    .module('app')
    .factory('Service', Service);
})();

HTML

  <body ng-app='app' ng-controller='ctrl'>
    Status : {{working.status}}<br>
    Status not updating : {{not_working}}<br>
    SomeValue : {{service.someValue}}
    <br>
    <button ng-click="changeStatus()">go</button>
  </body>

您可以看到Working Plunker

Angular将通过脏检查的实现来跟踪$scope上的更改。因此,当Angular应用程序中发生事件并调用$apply或$digest时,Angular将遍历所有$watch值,并相应地更新任何绑定值。

如果没有更新的controllerAs语法,您将希望将任何想要绑定到$scope对象上的值。然后,在Angular应用程序中触发的任何事件都将自动触发更新。

下面是一个将$scope.status.value绑定到三个DOM引用的简单演示:http://codepen.io/anon/pen/KdKrqe

直接回答您的问题:

  1. 不,由于Angular脏检查,您不需要为绑定值创建getter/setter。但是,电流:电流是不够的。这将把Angular之外的值重新分配到其$范围,并且根据Object类型,这将由值或引用指定。当您按值(数字、字符串、布尔值…(分配时,与原始值的任何"连接"都将丢失

  2. 是的,如果service.service是按值分配的,您将失去绑定,即您将无法更新services.status来更新$scope.status的值。如果您将其稍微更改为:$scope.services = services;,则将绑定$scope.services.status。

  3. 如果您使用上面的建议,任何更改都将反映在您的原始对象中:$scope.services = services;,那么,服务上的任何更改。会反映在您的原始对象中。

我认为这里的两个要点是理解JS中通过值/引用进行赋值,以及Angular如何通过脏检查实现绑定值。