通过服务传递数据而不更新第二个控制器

时间:2018-10-05 08:32:52

标签: angularjs

我试图在AngularJS中使用服务,并通过单击按钮将数据从一个控制器传递到另一个控制器。 我尝试过,可以看到服务值已更新,但是我无法在第二个控制器中检索,但是,我可以在第一个控制器中检索。

 <!DOCTYPE html>
    <html>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
    <body ng-app="myApp">

        <div ng-controller="myCtrl">
            <p>Search:<input type="text" ng-model="newValue"></p>
            <button ng-click="myFunc(newValue)">OK</button>

        </div>
        <div ng-controller="myCtrl2">
            {{receivedVal}}            
        </div>


        <script>
       var app= angular.module('myApp', []);
        app.controller('myCtrl',  function($scope,sharedProperties) {


            $scope.stringValue = sharedProperties.getString();

                $scope.myFunc = function(newValue) {  

                sharedProperties.setString(newValue);
                $scope.stringValue = sharedProperties.getString();
                console.log($scope.stringValue);
               //I am getting the value here by calling sharedProperties.getString();

                };

        });


        app.controller('myCtrl2',  function($scope,sharedProperties) {
            $scope.receivedVal = sharedProperties.getString();
            console.log($scope.receivedVal);
//But I am not getting the updated value here by calling sharedProperties.getString();
        });


        app.service('sharedProperties', function() {
        var stringValue = 'firstoccurence';     
        return {
            getString: function() {
                return stringValue;
            },
            setString: function(value) {
                stringValue = value;
            },        
        }
    });



        </script>

        </body>
    </html>

receivedVal 总是空白,即使服务正在更新。

2 个答案:

答案 0 :(得分:0)

第二个控制器中的值正在更新

但这并没有反映在:

<div ng-controller="myCtrl2">
{{receivedVal}}

</div>

因为ng-controller创建了新作用域

您应该像这样编写一种额外的方法: https://codepen.io/amar9312/pen/yRJKGj

答案 1 :(得分:0)

通过查看您的HTML代码;我可以看到两个控制器都已被实例化。

因此,当您在控制器2中执行$scope.receivedVal = sharedProperties.getString();时,您只能从服务中获得一次价值(注意:,您不会不断地从服务中观察到价值)。因此,在控制器2的模板中,应显示默认值firstoccurence

您实际上是在单击“确定”按钮时更新值,这反过来会更新服务中的值。但是您无法告诉角度,现在值已更改,那么控制器2应该会获得这个新值。

要激活所需的方案,您需要使用$broadcast$on,以便可以连续观察控制器1中发生的变化。

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
    <body ng-app="myApp">

        <div ng-controller="myCtrl">
            <p>Search:<input type="text" ng-model="newValue"></p>
            <button ng-click="myFunc(newValue)">OK</button>

        </div>
        <div ng-controller="myCtrl2">
            {{receivedVal}}   
            
            
            
            <button ng-click="thisWillGetValFromService()" >update this scope's value</button>
        </div>


        <script>
       var app= angular.module('myApp', []);
        app.controller('myCtrl',  function($rootScope,$scope,sharedProperties) {


            $scope.stringValue = sharedProperties.getString();

                $scope.myFunc = function(newValue) {  

                sharedProperties.setString(newValue);
                $scope.stringValue = sharedProperties.getString();
                console.log($scope.stringValue);
               //I am getting the value here by calling sharedProperties.getString();
                  $rootScope.$broadcast('greeting', newValue);

                };

        });


        app.controller('myCtrl2',  function($scope,sharedProperties) {
            $scope.receivedVal = sharedProperties.getString();
            console.log($scope.receivedVal);
//But I am not getting the updated value here by calling sharedProperties.getString();
          $scope.$on('greeting', function(ev,val){
               $scope.receivedVal = val
          })


           
        });


        app.service('sharedProperties', function() {
        var stringValue = 'firstoccurence';     
        return {
            getString: function() {
                return stringValue;
            },
            setString: function(value) {
                stringValue = value;
            },        
        }
    });



        </script>

        </body>

以上代码段将解决您的问题。

已更新:

请考虑您已定义路由配置的方案。因此,默认情况下,仅控制器1及其模板加载为HTML。然后您更新您的输入框,然后单击确定按钮。这样会将数据保存到服务中。

然后稍后考虑单击某些链接,您将应用重定向到控制器2的路由,因此此时控制器2将被实例化,$scope.receivedVal = sharedProperties.getString();将为您提供更新的值。

这只是何时加载模板(控制器)的问题,在这种情况下,您一次加载两个控制器,因此需要使用广播功能。但是,如果稍后要加载第二个组件,则可以随时使用服务。