AngularJS使用$ broadcast帮助控制器之间共享数据

时间:2015-09-18 10:43:08

标签: javascript angularjs angularjs-scope controllers data-sharing

我一直试图使用$ broadcast和$ on,但我无法让数据在两个控制器之间移动。

在我的主网页上,我有一个按钮,每次点击时会增加4个按钮:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body ng-app="app">
    <div ng-controller="mainCtrl">

        <button ng-click="add(4)"> 4 </button>

    </div>
    <script src="../Scripts/angular.js"></script>
    <script src="../assets/js/angular-grid.js"></script>
    <script src="../assets/controller/gods_controller.js"></script>
    <script src="../Scripts/angular-animate.js"></script>
</body>
</html>

在我的mainCtrl中,我有函数add()并使用$ broadcast来广播我的值:

var module = angular.module("app", ["angularGrid", "ngAnimate"])

module.controller("mainCtrl", function ($scope, $rootScope) {

var total = 0

    $scope.add = function (x) {
        total += x;

        $rootScope.$broadcast('totalBroadcast', total)

    }

});

然后我使用$ on接收广播弹出第二个控制器:

module.controller('popUpCtrl', function ($scope) {


     $scope.$on('totalBroadcast', function(events, args){

  $scope.total = args;
  })

   })

然后我的弹出HTML使用第二个控制器和$ scope.total作为表达式:

    <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body ng-app="app">
    <div ng-controller="popUpCtrl">

       <p>The total is: {{total}}</p>

    </div>
    <script src="../Scripts/angular.js"></script>
    <script src="../assets/js/angular-grid.js"></script>
    <script src="../assets/controller/gods_controller.js"></script>
    <script src="../Scripts/angular-animate.js"></script>
</body>
</html>

似乎没有数据传递给我的第二个控制器,表达式根本没有显示任何内容。

修改

我也尝试过使用某项服务,上面的HTML保持不变,但现在我已经添加了服务

module.factory('myService', function () {

    var total = 0;

    var setTotal = function (x) {
        total = x;
    }

    var getTotal = function () {
        return total;
    };

    return {
        setTotal: setTotal,
        getTotal: getTotal
    }


    });

我的主控制器和广告功能现在是:

 module.controller("mainCtrl", function ($scope, myService) {

    var total = 0

    $scope.add = function (x) {

        myService.setTotal(x)
    }

 });

我的popupCtrl控制器现在是这样的:

module.controller('popUpCtrl', function ($scope, myService) {


    $scope.total = myService.getTotal();

})
我弹出窗口中的

{{total}}现在表示为&#34; 0&#34; var total等于我的服务。所以现在使用服务传输数据,但是setTotal()方法现在没有按照add()函数的指示设置var。我已将我的服务注入两个控制器的依赖项。

3 个答案:

答案 0 :(得分:1)

添加手表或广播以在控制器之间共享数据是一种非常糟糕的做法,这样做是为了在两个控制器中注入公共服务。

  

服务为我们提供了一种共享数据和功能的简便方法   我们的应用程序。我们创建的服务是可以的单身人士   注入控制器和其他服务,使它们成为理想的选择   写可重用代码的地方。

关注其链接https://thinkster.io/a-better-way-to-learn-angularjs/services

答案 1 :(得分:0)

您获得零的原因是您的控制器仅在加载时分配给myService.getTotal()的值。这意味着当您更改total变量时,它将不会更新。

您需要$watch获取更新:

$scope.$watch(function () {
    return myService.getTotal();
}, function (newVal) {
    $scope.total = newVal;
});

此外,您似乎正在使用新页面初始化您的应用。这不是角度如何工作。阅读angular route,然后尝试按照我的建议去做。如果您将其设为单页应用程序,它应该可以工作。

答案 2 :(得分:0)

我确实找到了我的初始问题的解决方案,即使用localStorage.setItem("num", "num")将数据存储在浏览器中。这似乎是专门为在标签/窗口之间共享数据而开发的,因此可以通过localStorage.getItem("num")访问。

这回答了我原来的问题,但我现在想要total动态更新。目前它仅在刷新时更新。任何提示将不胜感激。

编辑(以上答案)

在我的第二个弹出窗口中使用此事件侦听器 -

window.addEventListener('storage', function (event) {
        $scope.total = parseInt(event.newValue);
        $scope.$apply();
    });

我能够访问存储并将其绑定到HTML中的表达式。请记住$ scope.apply()需要在这里调用,因为total超出了范围。

此处提供更多详细信息 - https://developer.apple.com/library/safari/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/Name-ValueStorage/Name-ValueStorage.html