动态更改控制器 $scope 变量
Changing controller $scope vars dynamically
所以。我有简单的控制器和服务:
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;
};
})
;
然后我在 anotherService
中有一些 $interval,每 1 秒获取一次数据并调用 FieldService.setName
:
.service('UpdateService', function($http, FieldService) {
$interval(function() {
$http.get('/somUrl')
.then(function(response) {
FieldService.setName(response.name);
});
});
})
但这不会改变我的 HTML。
如果我在返回值 getName
中从原始对象切换到对象,那么它正在工作。
还有其他方法吗?我个人认为,我创建的这个结构很糟糕,但无法理解应该如何完成。
我会将我的 $interval 函数移到控制器中,然后每秒更新一个 $scope 属性。然后 Angular 将负责渲染。或者您还必须在控制器中使用 $interval 函数,它每秒获取服务内容(即 FieldService.getName)。
JavaScript 始终是按值传递,但是当您的变量是对象时,'value' 实际上是对该对象的引用。所以在你的例子中,你得到的是对象的引用,而不是值。因此,当对象发生变化时,该变化不会像基元那样传播。
您的代码似乎也有点不正确。您正在将 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;
}
});
})
我会这样使用它:
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);
})
您可以通过多种方式实现这一目标。没有办法就是最好的办法。因人而异。
希望对您有所帮助。
有几种方法可以解决这个问题。
1) 将 $interval 移动到控制器。然后你将有一个变量,它保存该数据,你可以在视图中绑定它
2) 您可以使用 AngularJs 事件。$rootScope 将帮助您发送信号并在任何您想要的地方捕获它。
如果您想了解有关此解决方案的更多信息,可以在此处查看:
http://www.w3docs.com/snippets/angularjs/bind-value-between-service-and-controller-directive.html
所以。我有简单的控制器和服务:
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;
};
})
;
然后我在 anotherService
中有一些 $interval,每 1 秒获取一次数据并调用 FieldService.setName
:
.service('UpdateService', function($http, FieldService) {
$interval(function() {
$http.get('/somUrl')
.then(function(response) {
FieldService.setName(response.name);
});
});
})
但这不会改变我的 HTML。
如果我在返回值 getName
中从原始对象切换到对象,那么它正在工作。
还有其他方法吗?我个人认为,我创建的这个结构很糟糕,但无法理解应该如何完成。
我会将我的 $interval 函数移到控制器中,然后每秒更新一个 $scope 属性。然后 Angular 将负责渲染。或者您还必须在控制器中使用 $interval 函数,它每秒获取服务内容(即 FieldService.getName)。
JavaScript 始终是按值传递,但是当您的变量是对象时,'value' 实际上是对该对象的引用。所以在你的例子中,你得到的是对象的引用,而不是值。因此,当对象发生变化时,该变化不会像基元那样传播。
您的代码似乎也有点不正确。您正在将 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;
}
});
})
我会这样使用它:
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);
})
您可以通过多种方式实现这一目标。没有办法就是最好的办法。因人而异。
希望对您有所帮助。
有几种方法可以解决这个问题。
1) 将 $interval 移动到控制器。然后你将有一个变量,它保存该数据,你可以在视图中绑定它
2) 您可以使用 AngularJs 事件。$rootScope 将帮助您发送信号并在任何您想要的地方捕获它。
如果您想了解有关此解决方案的更多信息,可以在此处查看: http://www.w3docs.com/snippets/angularjs/bind-value-between-service-and-controller-directive.html