动态更改控制器$ scope vars

时间:2015-08-10 13:09:56

标签: javascript angularjs angularjs-service angularjs-controller

因此。我有简单的控制器和服务:

>>> print(a)
array('B', [1, 2, 3])

然后我在angular .module('field', []) .controller('FieldController', function(FieldService) { var vm = this; vm.name = FieldService.getName(); }) .service('FieldService', function() { var name = 'John' this.getName = function() { return name; }; this.setName = function(newName) { name = newName; }; }) ; 中有一些$ interval,每隔1秒获取一次数据并调用anotherService

FieldService.setName

但它不会改变我的HTML。 如果我在返回值 .service('UpdateService', function($http, FieldService) { $interval(function() { $http.get('/somUrl') .then(function(response) { FieldService.setName(response.name); }); }); }) 时从原始状态切换到对象,那么它正在工作。

还有其他方法吗?我个人认为,我创建的这个结构很糟糕,但无法理解应该如何完成。

4 个答案:

答案 0 :(得分:1)

JavaScript总是按值传递,但是当您的变量是对象时,'值'实际上是对象的引用。因此,在您的情况下,您将获得对象的引用,而不是值。因此,当对象发生变化时,该变化不会像原语一样传播。

您的代码似乎也有点不正确。您将response.name的值设置为FieldService.setName,这实际上是一个函数。

如果您想使用已列出的getter / setter方法,那么您可以使用事件让控制器知道名称已更改。

.service('UpdateService', function($http, FieldService, $rootScope) {
        $interval(function() {
            $http.get('/somUrl')
                .then(function(response) {
                    FieldService.setName(response.name);
                    $rootScope.$broadcast('nameChanged', {
                        name : response.name
                    });
                });
        });
    })

  .controller('FieldController', function(FieldService, $scope) {
         var vm = this;
         vm.name = FieldService.getName();

         $scope.$on('nameChanged', function (evt, params) {
             vm.name = params.name;
         });
    })

另一种实现此目的的方法是在控制器中的服务变量上使用$scope.$watch

.controller('FieldController', function($scope, FieldService) {
         $scope.name = FieldService.getName();
         $scope.$watch(function () {
            return FieldService.getName();
         }, function (newVal, oldVal) {
            if (newVal !== oldVal) {
                $scope.name = newVal;
            }            
         });
    })

答案 1 :(得分:0)

我会将$ interval函数移动到控制器中,然后每秒更新$ scope属性。然后Angular将负责渲染..或者您还必须在控制器中使用$ interval函数,该函数每秒获取服务内容(即FieldService.getName)。

答案 2 :(得分:0)

我会这样用它:

angular
    .module('field', [])
    .controller('FieldController', function($scope, FieldService) {
         $scope.name = function(){
            FieldService.getName();
         };
    })
    .service('FieldService', function() {
         var name = 'John'
         this.getName = function() {
             return name;
         };
         this.setName = function(newName) {
             name = newName;
         };
    });

使用html中的name()查看更新值。
和您的其他服务:

.service('UpdateService', function($http, FieldService) {
        $interval(function() {
            $http.get('/somUrl')
                .then(function(response) {
                    FieldService.setName(response.name);
                });
        }, 1000);
    })

您可以通过多种方式实现这一目标。绝不是最好的方法。取决于人与人之间。

希望这有帮助。

答案 3 :(得分:0)

有几种方法可以解决这个问题。

1)将$ interval移动到控制器。然后您将拥有一个变量,该变量保存该数据并且您可以在视图中绑定它

2)您可以使用AngularJs Events 。$ rootScope将帮助您发送信号并在任何地方捕获它。

如果您想了解有关此解决方案的更多信息,可以在此处查看: http://www.w3docs.com/snippets/angularjs/bind-value-between-service-and-controller-directive.html