我在控制器中使用这个 Angular 工厂错误吗?

Am I using this Angular factory wrong from controller?

我有一个非常简单的工厂:

var tv3Services = angular.module('tv3Services',[]);

tv3Services.factory('PanelService', [function(){
    var _panel = "";
    return {
        getPanel: function() {return _panel;},
        changePanel: function(newPanel) {_panel = newPanel;}
    };
}]);

以及使用它的控制器:

var tv3App = angular.module('tv3App', ['tv3Services']);

tv3App.controller('AdminController', function($scope,PanelService) {


    $scope.panel = PanelService.getPanel();

    $scope.changePanel = function(panel) {
        PanelService.changePanel(panel);
    };

    $scope.changePanel("hola");

});

这个简单的标记:

<html ng-app="tv3App"> 

  <head>
    <script src="service.js"></script>
    <script src="controller.js"></script>
  </head>

  <body ng-controller="AdminController">
    <h1>This should send a glyphicon when panel ONLY is same as "start"</h1>

    <div class="text-center">
      <span ng-show="panel=='start'" class="glyphicon glyphicon-star"></span>
    </div>

    <strong>Panel is set to "hola" though ...</strong>
  </body>

</html>

但是,它根本无法正常工作。面板似乎不受任何约束。我正在调用 $scope.changePanel("start"); 以便触发服务并为其分配一个值。

为什么这不起作用?

我得到了一个plunkr example

您需要调用 $scope.panel = PanelService.getPanel(); 来设置服务具有的更新值,或者您可以放置​​ $watch on service variable 并在此基础上更新 $scope.panel 值。

代码

$scope.changePanel = function(panel) {
    PanelService.changePanel(panel);
    $scope.panel = PanelService.getPanel();
};

Plunkr Here

编辑 1

你想要的东西可以通过将服务 getter 方法引用分配给范围变量来实现,比如 scope.panel = PanelService.getPanel 并且在 UI 上绑定它时你可以使用 {{panel()}} 因此面板将在每个 digest 周期调用服务 getter

HTML

<strong>Panel is set to "hola" though ... But got {{panel()}}</strong>

控制器

tv3App.controller('AdminController', function($scope, $http, PanelService) {
    $scope.panel = PanelService.getPanel; //asigning getter reference
    $scope.changePanel = function(panel) {
        PanelService.changePanel(panel);
    };
    $scope.changePanel("start");
});

Updated Plunkr

Refer SO 了解更多信息

编辑 2

另一种方法,你可以在服务上维护一个数组,并将新值推入其中,一旦你调用 getter 服务方法,它引用就会附加到 $scope 变量,每当更新时发生在服务更改中也会反映在范围变量中。

服务

var tv3Services = angular.module('tv3Services', []);

tv3Services.factory('PanelService', [
  function() {
    var _panel = [];
    return {
      getPanel: function() {
        return _panel;
      },
      changePanel: function(newPanel) {
        _panel.push(newPanel);
      }
    };
  }
]);

控制器

var tv3App = angular.module('tv3App', ['tv3Services']);

tv3App.controller('AdminController', function($scope, $http, PanelService) {

    $scope.panel = PanelService.getPanel(); //scope gets binded to the service variable

    $scope.changePanel = function(panel) {
        PanelService.changePanel(panel);
    };

    $scope.changePanel("start");

});

HTML

<body ng-controller="AdminController">
    <h1>This should send a glyphicon when panel ONLY is same as "start"</h1>
    <div class="text-center">
        <span ng-show="panel=='start'" class="glyphicon glyphicon-star"></span>
    </div>
    <strong>Panel is set to "hola" though ... But got {{panel[0]}}</strong>
</body>

编辑2 Plunkr Here , One more good example in Plunkr

谢谢。

在您使用服务的地方,请尝试明确声明您的服务名称,以防缩小会重命名您的变量。试试这个;

tv3App.controller('AdminController',['$scope','PanelService',
function($scope,PanelService) {
    $scope.panel = PanelService.getPanel();
    $scope.changePanel = function(panel) {
        PanelService.changePanel(panel);
    };

    $scope.changePanel("hola");
}]);