从工厂访问范围

时间:2017-10-18 12:18:07

标签: javascript angularjs

我使用工厂作为单身人士。我想从这个工厂访问控制器的范围。它归结为以下代码:

angular.module('foo', [])
.controller('fooCtrl', function($scope, testFac) {
    $scope.example = "I wanna change";

    testFac.change = function(change){
        $scope.example = change;
    }
})

.factory('testFac', function($timeout){
    var testFac= {}

    $timeout(function(){
        testFac.change("You changed")
    }, 3000)

    return testFac;
})

此刻我在控制器中声明了该功能,因为那时我在正确的范围内,我可以从工厂调用该功能。但它似乎不是一个非常优雅的解决方案。 有更好的解决方法吗? 出于测试目的,请参阅此fiddle

2 个答案:

答案 0 :(得分:2)

  

我将工厂用作单身人士

工厂/服务/提供商是单身人士

  

我想从这家工厂访问控制器的范围。

使用工厂内的范围进行操作并不是一个好习惯。在angular中,控制器的范围仅用于将View绑定到Controller。

关于您的代码:

.factory('testFac', function($timeout){
    var testFac= {}

    $timeout(function(){
        testFac.change("You changed")
    }, 3000)

    return testFac;
})

它不是工厂的目的。您可以编写第二个控制器或指令

  

有没有更好的方法来解决这个问题?

是的,您可以使用$broadcast

  

将事件名称向下调度到所有子范围(及其子级),通知已注册的$ rootScope.Scope侦听器。

答案 1 :(得分:0)

使用RxJS

推送服务中的值
  

我想避免使用广播

使用RxJS Extensions for Angular构建服务。

<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/rx/dist/rx.all.js"></script>
<script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script>
var app = angular.module('myApp', ['rx']);

app.factory("DataService", function(rx, $timeout) {
  var subject = new rx.Subject(); 
  var data = "I wanna change";

  $timeout(function(){
      subject.onNext("You changed");
  }, 3000);

  return {
      set: function set(d){
        data = d;
        subject.onNext(d);
      },
      get: function get() {
        return data;
      },
      subscribe: function (o) {
         return subject.subscribe(o);
      }
  };
});

然后只需订阅更改。

app.controller('displayCtrl', function(DataService) {
  var $ctrl = this;

  $ctrl.data = DataService.get();
  var subscription = DataService.subscribe(function onNext(d) {
      $ctrl.data = d;
  });

  this.$onDestroy = function() {
      subscription.dispose();
  };
});

客户可以使用DataService.subscribe订阅更改,生产者可以使用DataService.set推送更改。

The DEMO

&#13;
&#13;
angular.module('app', ['rx'])

.factory("DataService", function(rx, $timeout) {
  var subject = new rx.Subject(); 
  var data = "I wanna change";

  $timeout(function(){
      subject.onNext("You changed");
  }, 3000);

  return {
      set: function set(d){
        data = d;
        subject.onNext(d);
      },
      get: function get() {
        return data;
      },
      subscribe: function (o) {
         return subject.subscribe(o);
      }
  };
})

.controller('ctrl', function(DataService) {
  var $ctrl = this;

  $ctrl.data = DataService.get();
  var subscription = DataService.subscribe(function onNext(d) {
      $ctrl.data = d;
  });

  this.$onDestroy = function() {
      subscription.dispose();
  };
})
&#13;
<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/rx/dist/rx.all.js"></script>
<script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script>


<body ng-app="app" ng-controller="ctrl as $ctrl">
    <h1>RxJS DEMO</h1>
    <p>Data= {{$ctrl.data}}</p>
</body>
&#13;
&#13;
&#13;