【问题标题】:$watch a service variable or $broadcast an event with AngularJS$watch 服务变量或 $broadcast 使用 AngularJS 的事件
【发布时间】:2013-08-27 03:28:45
【问题描述】:

我正在使用服务在控制器之间共享数据。修改变量时,应用程序必须更新 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();
    };
}]);

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

在另一个选项中,我使用服务中的函数来修改 $broadcast 事件的变量。该事件由控制器监听,然后更新 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>" );

        } );

【问题讨论】:

    标签: angularjs broadcast watch


    【解决方案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/ 相同的想法稍微清理了一下。

    【讨论】:

    • 谢谢,很抱歉我没有提供更多细节。我编辑了帖子。
    • 我仍然没有看到需要删除和添加 dom。但如果你想那样,我说$watch
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    • 2018-03-15
    • 1970-01-01
    相关资源
    最近更新 更多