AngularJS:在控制器中为提供者的$get方法使用$watch
我一直在四处寻找,但找不到解决方案。我有一个提供程序,它只使用$get函数返回RANDOM,还有另一个方法将RANDOM设置为数组中的随机字符串。在从配置中设置RANDOM之后,我可以从配置中访问它的当前值,但是即使存在$watch,控制器也不会检测到对RANDOM的更改。为了您的方便,我在下面附上了我的代码 提供者:AngularJS:在控制器中为提供者的$get方法使用$watch,angularjs,angular-ui-router,Angularjs,Angular Ui Router,我一直在四处寻找,但找不到解决方案。我有一个提供程序,它只使用$get函数返回RANDOM,还有另一个方法将RANDOM设置为数组中的随机字符串。在从配置中设置RANDOM之后,我可以从配置中访问它的当前值,但是即使存在$watch,控制器也不会检测到对RANDOM的更改。为了您的方便,我在下面附上了我的代码 提供者: app.provider('sets', function (){ var sets= ['gogreen', 'gored', 'tekkon', 'temple', 'com
app.provider('sets', function (){
var sets= ['gogreen', 'gored', 'tekkon', 'temple', 'comehome'];
var random = sets[Math.round(Math.random() * (sets.length - 1))];
return {
set: function () {
random = sets[Math.round(Math.random() * (sets.length - 1))];
},
take: function (){
return random
},
$get: function () {
console.log("$get: " + random);
return {
random
};
}
};
});
我将使用这种形式的设置,稍后将其注入到我的配置中,如下所示。注意:我使用的是UI路由器
$stateProvider
.state('root', {
url : "/{name}",
views: {
"canvasContainer": {
templateUrl: function (stateParams) {
if (angular.isDefined(stateParams.name) && stateParams.name !== 'p' && stateParams.name !== '') {
return 'templates/canvas/cnv.' + stateParams.name + '.html';
} else {
setsProvider.set();
console.log("config: " + setsProvider.$get().random);
return 'templates/canvas/cnv.'+setsProvider.$get().random+'.html';
}
},
controller: 'canvasController'
}
}
})
我有一个函数可以重新加载当前状态
$scope.refresh = function (){
$state.reload();
};
在另一个控制器中,我有一个$watch检测来自我的提供商的set.random上的更改。但是,未正确检测到更改
$scope.set= sets.random;
$scope.$watch(
function(scope) {
return sets.random;
},
function(newValue, oldValue) {
console.log("New value is: " + sets.random);
$scope.set = newValue;
}
);
这是我在控制台中得到的输出:
$get: gored
$get: gogreen
config: gogreen
$get: gogreen
$watch: gored
refresh(): gored
$get: temple
config: temple
$get: temple
$watch: gored
refresh(): gored
$get: tekkon
config: tekkon
$get: tekkon
$watch: gored
refresh(): gored
$get: tekkon
config: tekkon
$get: tekkon
$watch: gored
refresh(): gored
$get: gored
config: gored
$get: gored
$watch: gored
refresh()和$watch位于两个不同的控制器中,但它们不断释放相同的旧值。所以我的假设是控制器不能跟踪随机变量。我对这一切都很陌生,任何帮助都将不胜感激
另外,我的控制器设置如下:
app.controller('canvasController', ['sets', function(sets){
//-----Code----
}]);
正如Mathew所提到的,使用$broadcast可能会有帮助,但是我无法用这个方法得到任何结果,因为它不断地向我抛出不同的错误。但我最终还是能够通过修改代码来实现这一点,而解决方案实际上非常简单 我修改了我的提供者,如下所示:
app.provider('sets', function (){
var sets= ['gogreen', 'gored', 'tekkon', 'temple', 'comehome'];
var random;
return {
set: function () {
random = sets[Math.round(Math.random() * (sets.length - 1))];
},
$get: function () {
// console.log("$get: " + random);
return {
'random' : random,
set : function () {
random = sets[Math.round(Math.random() * (sets.length - 1))];
return random;
},
get : function () {
return random;
}
};
}
};
});
$scope.refresh = function (){
sets.set();
$state.reload();
};
stateProvider仍如上述问题所示。
refresh()函数修改如下:
app.provider('sets', function (){
var sets= ['gogreen', 'gored', 'tekkon', 'temple', 'comehome'];
var random;
return {
set: function () {
random = sets[Math.round(Math.random() * (sets.length - 1))];
},
$get: function () {
// console.log("$get: " + random);
return {
'random' : random,
set : function () {
random = sets[Math.round(Math.random() * (sets.length - 1))];
return random;
},
get : function () {
return random;
}
};
}
};
});
$scope.refresh = function (){
sets.set();
$state.reload();
};
最后,我甚至不需要$watch或$broadcast。值在提供程序中更改时在控制器中动态更新
我通过遵循某些逻辑和模式找到了这个解决方案,但不知道为什么它会起作用。对于直接从$get检索的对象在控制器中不会自动更新,但如果从$get内的函数检索,则会自动更新的原因,请给出任何解释。基本上,这两者之间的区别是:
set: function () {
random = sets[Math.round(Math.random() * (sets.length - 1))];
},
$get: function () {
console.log("$get: " + random);
return {
random
};
}
这是:
set: function () {
random = sets[Math.round(Math.random() * (sets.length - 1))];
},
$get: function () {
// console.log("$get: " + random);
return {
'random' : random,
set : function () {
random = sets[Math.round(Math.random() * (sets.length - 1))];
return random;
},
get : function () {
return random;
}
};
}
谢谢提供者返回的服务对象需要在rootScope上广播该值已更改,然后控制器可以侦听该事件。在作用域上使用观察者是行不通的,因为只有当作用域的父级发生变化时,才会对其进行消化。因为服务可以在没有任何范围更改的情况下进行更新。“守望者”不会开火。@MathewFoscarini你能再详细一点吗?我尝试在get方法中使用$rootScope.$broadcast,但此后整个应用程序停止运行。不会抛出任何错误。也尝试了$injector,但得到了相同的结果。先谢谢你