$使用AngularJS观察服务变量或$广播事件

时间:2013-08-24 00:20:11

标签: angularjs broadcast watch

我使用服务在控制器之间共享数据。应用程序必须在修改变量时更新DOM。我找到了两种方法,你可以在这里看到代码:

http://jsfiddle.net/sosegon/9x4N3/7/

myApp.controller( "ctrl1", [ "$scope", "myService", function( $scope, myService ){
    $scope.init = function(){
        $scope.myVariable = myService.myVariable;
    };
}]);

myApp.controller( "ctrl2", [ "$scope", "myService", function( $scope, myService ){
    $scope.increaseVal = function(){
        var a = myService.myVariable.value;
        myService.myVariable.value = a + 1;
    };
}]);

http://jsfiddle.net/sosegon/Y93Wn/3/

myApp.controller( "ctrl1", [ "$scope", "myService", function( $scope, myService ){
    $scope.init = function(){
        $scope.increasedCounter = 1;
        $scope.myVariable = myService.myVariable;
    };
    $scope.$on( "increased", function(){
        $scope.increasedCounter += 1;
    }
}]);

myApp.controller( "ctrl2", [ "$scope", "myService", function( $scope, myService ){
    $scope.increaseVal = function(){
        myService.increaseVal();
    };
}]);

在第一种情况下,我与控制器共享服务中的变量,并在指令中查看$。在这里,我可以直接在此控制器或共享它的任何其他控制器中修改变量,并更新DOM。

在另一个选项中,我使用服务中的函数来修改$广播事件的变量。该事件由控制器监听,然后更新DOM。

我想知道哪个选项更好以及原因。

感谢。

修改

jsFiddle中的代码是真实代码的简化版本,它具有更多对象和功能。在服务中,myVariable的value字段实际上是一个对象,其信息远远多于基本类型;必须在DOM中显示和更新该信息。每个更改都设置了对象myVariable.value:

myVariable.value = newValue;

当发生这种情况时,必须更新所有DOM元素。由于myVariable.value中包含的信息是可变的,属性的数量会发生变化(我不能使用数组),因此删除DOM元素并创建新元素要容易得多。我在指令中所做的事情(但在实际代码中有更多元素):

scope.$watch( "myVariable.value", function( newVal, oldVal ){

            if( newVal === oldVal ){

                return;

            }

            while( element[0].children.length > 0 ){

                element[0].removeChild( element[0].firstChild );

            }


            var e = angular.element( element );
            e.append( "<span>Value is: " + scope.myVariable.value + "</span>" );

        } );

1 个答案:

答案 0 :(得分:1)

您的代码过于复杂。我不确定你在用这个指令做什么。

您没有$watch$broadcast任何内容。

您的服务中有一个具有原语的对象。在ctrl1中,您将对象分配给$scope(这很好,因为如果我们将其分配给基元,那么肯定需要$watch,如here所示。

到目前为止一切顺利。为了增加价值,有一种简单的方法就是myVal++不需要临时变量。

对于该指令,我不确定您的目标是什么,我将其简化为您需要将该示例用于工作的内容。您不需要$watch也不需要$broadcastctrl1知道对myVariable对象所做的更改,因此如果更改,您会注意到它。

代码:

var myApp = angular.module( "myApp", [] );

myApp.provider( "myService", function(){

    var myVariable = {
        value: 0
    };
    this.$get = function(){
        return {
            myVariable: myVariable,
            increase: function() {
                myVariable.value++;
            }
        };
    };
});

myApp.directive( "dir1", function(){
    return {
        restrict: 'EA',
        template: '<div>value: {{myVariable.value}}</div>',
        replace: true
    };
});


myApp.controller("ctrl1", ["$scope", "myService", function($scope, myService){
    $scope.myVariable = myService.myVariable;
}]);

myApp.controller( "ctrl2", [ "$scope", "myService", function( $scope, myService ){
    $scope.increaseVal = myService.increase;
}]);

查看:

<body ng-app = "myApp">
    <div dir1="myVariable.value" ng-controller = "ctrl1">
    </div>

    <div ng-controller = "ctrl2">
        <button ng-click = "increaseVal()">
            Increase
        </button>
    </div>


</body>

这是我的分叉小提琴:http://jsfiddle.net/uWdUJ/同样的想法有点清理。