我有一个异步提取数据并将其提供给控制器的服务。在那里,它被附加到$scope
并在视图中使用
我不明白的是更新方面的差异,具体取决于控制器中此服务的使用方式。
该服务不提供数据承诺,而是公开数据本身。我已经通过超时模拟了它:
(编辑:我已将初始化添加到Opt
变量,以表明这不能解决问题。)
app.service("Options", ["$q", "$timeout", function ($q, $timeout) {
var Opt = {
people:[],
symbols:[],
countries:[]
};
$timeout(function () {
Opt.people = [ {frst: "Johnny", last: "Walker"},
{frst: "Jack", last: "Daniels"},
{frst: "Jim", last: "Bean"} ];
}, 1000);
$timeout(function () {
Opt.symbols = [ {name: "Pi", descr: "circles"},
{name: "Phi", descr: "ratios"},
{name: "Psi", descr: "waves"},
{name: "Chi", descr: "distributions"} ];
}, 2000);
$timeout(function () {
Opt.cities = [ {name: "Amsterdam", country: "Netherlands"},
{name: "Cairo", country: "Egypt"},
{name: "Santiago", country: "Chile"} ];
}, 3000);
/* etc */
return Opt;
}]);
然后在控制器中使用它,如下所示:
app.controller("Ctrller", ["$scope", "Options", "$timeout", function ($scope, Options, $timeout) {
$scope.options = Options; //updating
$scope.symbols = $scope.options.symbols; //not updating
$scope.symbols = Options.symbols; //not updating either
$timeout(function(){
$scope.symbols = $scope.options.symbols; //updating
}, 4000);
}]);
我在Plnkr here中创建了一个现场演示。
如您所见,视图中的第二个select
元素(以及$scope
的'符号'属性)在4而不是2秒后更新。如果控制器中没有$timeout
,那么这当然不会发生。
为什么会这样?为什么这些变化没有通过?
谢谢!
答案 0 :(得分:1)
您正试图在$scope.symbols
服务返回的对象中存在$scope.options.symbols
数组之前将Options.symbols
分配给symbols
或Options
,所以它( $scope.symbols
)被赋予undefined
,而不是对符号对象的引用。您可以通过在尝试分配之前添加几个控制台语句来查看此内容。由于symbols
对象尚未存在,因此您的$scope.symbols
变量无法引用它。
这不是people
或cities
的问题,因为您通过$scope.options
对象访问它们,该对象引用了由Opt
对象返回的Options
对象ng-repeats
服务。由于基准引用保持不变,因此people
会看到对cities
和Options.symbols
子对象的更改。
如果您真的想将$scope.symbols
分配给$scope.options.symbols
,可以通过$scope.$watch('options.symbols', function(value) {
$scope.symbols = value;
});
上的观看完成:
people
更新示例plunker后编辑
修订后的plunker仍然表现出相同的行为,因为cities
中正在覆盖已初始化的symbols
,$timeout
和=
。如果您希望保持引用相同,则不得使用$timeout
中的$timeout(function () {
results = [ {name: "Pi", descr: "circles"},
{name: "Phi", descr: "ratios"},
{name: "Psi", descr: "waves"},
{name: "Chi", descr: "distributions"} ];
angular.forEach(results, function(result) {
Opt.symbols.push(result);
});
}, 2000);
运算符。一种选择是遍历返回的列表并使用推送添加每个项目:
Opt.symbols
Here is a revised plunker with my suggested changes.
可能有更好的方法来实现这一点,但关键是你不能将Opt.symbols
重新分配给其他对象(即使其他对象也是一个数组)。
另一种方法是将$scope.symbols
更改为包含数组的对象,引用Opt.symbols
指向对象(Opt = {
people: [],
symbols: {},
cities: []
}
$timeout(function() {
Opt.symbols.values = [ {name: "Pi", descr: "circles"},
{name: "Phi", descr: "ratios"},
{name: "Psi", descr: "waves"},
{name: "Chi", descr: "distributions"} ];
}, 2000);
)并查看内部值。
ng-options="s as s.name for s in symbols.values"
如果你走了那条路,你需要调整你的ng选项,看起来像,
$timeout
Here is a working plunker of this approach.
除了我给出的两个示例之外,您还可以采取其他方法,这对您的项目必须做出决定是有意义的。关键点在于,Opt.symbols
您无法重新分配$scope.symbols
的值并期望{{1}}引用新值。
答案 1 :(得分:0)
在index.html中,您正确指定了'options.people'和'options.options'的ng-options,但忘了为'symbols'指定
在:
ng-options="s as s.name for s in symbols"
后:
ng-options="s as s.name for s in options.symbols"
这是新的傻瓜: