Javascript AngularJS:更改$rootScope变量不会更改ng模型中的第一个选定选项
我有一个我似乎无法解决的具体问题 在html中,我有以下代码:Javascript AngularJS:更改$rootScope变量不会更改ng模型中的第一个选定选项,javascript,angularjs,angularjs-rootscope,javascript-inheritance,Javascript,Angularjs,Angularjs Rootscope,Javascript Inheritance,我有一个我似乎无法解决的具体问题 在html中,我有以下代码: <select ng-model="$parent.proizvod" ng-options="i.id_proizvod as i.proizvod for i in proizvodiServer"> <option>Select</option> </select> 因此,当页面首次加载时,将选择第一个选项。如果我更改$rootScope.proizvod='1';到
<select ng-model="$parent.proizvod" ng-options="i.id_proizvod as i.proizvod for i in proizvodiServer">
<option>Select</option>
</select>
因此,当页面首次加载时,将选择第一个选项。如果我更改$rootScope.proizvod='1';到$rootScope.proizvod='3';它将加载第三个选项
现在,当您选择某个其他值时,它会将其存储在$rootScope.proizvod中,但稍后,在某些函数中,我想将$rootScope.proizvod重置回“1”,它似乎不起作用
我错过了什么
另外,如果没有$parent.proizvod,我的选择甚至不会更改$rootScope.proizvod值
编辑:这是另一个功能:
$rootScope.upisPodataka = function() {
setTimeout(function () {
$rootScope.proizvod = '1';
$scope.$apply();
}, 2000);
$state.go('app.podesenost_grilla', {}, {
reload: true
});
只需单击按钮即可调用upisPodataka函数。使用ng模型=“$parent.proizvod”不保证在所有情况下都更新$rootScope
新的AngularJS开发人员通常没有意识到ng repeat、ng switch、ng view、ng include和ng if都会创建新的子作用域,因此当涉及到这些指令时,问题往往会出现
-
如果ng模型在子范围中设置值。子作用域获取自己的属性,该属性隐藏/隐藏同名的父属性。这不是AngularJS正在做的事情——这是JavaScript原型继承的工作方式。阅读维基
所以问题变成了它应该是$parent.$parent.proizvod吗?或者$parent.$parent.$parent.proizvod?用试错法来做吗
更稳健的方法是使用更新变量
<select ng-model="vm.proizvod" ng-change="vm.update()"
ng-options="i.id_proizvod as i.proizvod for i in proizvodiServer">
<option>Select</option>
</select>
<>而不是使用$ROOTVICE,考虑使用A来存储变量。
$rootScope存在,但可用于邪恶
AngularJS中的作用域形成一个层次结构,典型地从树顶部的根作用域继承。通常可以忽略这一点,因为大多数视图都有自己的控制器,因此也有自己的作用域
有时,您希望将某些数据片段设置为整个应用程序的全局数据。对于这些,您可以注入$rootScope并像其他任何作用域一样在其上设置值。由于作用域继承自根作用域,这些值将可用于附加到指令(如ng show)的表达式,就像本地$scope上的值一样
当然,全局状态很糟糕,您应该节约使用$rootScope,就像您希望在任何语言中使用全局变量一样。特别是,不要将其用于代码,只用于数据。如果您想在$rootScope上安装一个函数,那么最好将它安装到一个服务中,该服务可以被注入到需要的地方,并且更易于测试
相反,不要创建一个服务,它的唯一目的是存储和返回数据位
使用$timeout而不是window.setTimeout
包装windows.setTimeout并将其与AngularJS框架及其摘要周期集成。那么就不需要$apply了
此外,测试时可以使用$timeout.flush。显示其他功能它与控制器中的功能基本相同。我现在编辑了这个问题。为什么要使用rootscope来跟踪选择选项?所有作用域都将继承该值。这是一个糟糕的设计。将该值附加到控制器的作用域。另外,使用$setTimeout代替setTimeout并手动触发摘要循环。$setTimeout将在$apply中为您解决这个问题。我使用$rootScope是因为我在2个控制器中使用了这个变量。@MarcusH包装窗口的Angular服务。setTimeout是$timeout,请参阅。似乎工作得很完美!不过有一件事,我知道子范围,所以我在上面加了$parent,但似乎我还没有完全掌握角度范围!谢谢
<select ng-model="vm.proizvod" ng-change="vm.update()"
ng-options="i.id_proizvod as i.proizvod for i in proizvodiServer">
<option>Select</option>
</select>
vm.update = function () {
$rootScope.proizvod = vm.proizvod;
console.log($rootScope.proizvod);
});
$rootScope.upisPodataka = function() {
//setTimeout(function () {
$timeout(function () {
$rootScope.proizvod = '1';
//$scope.$apply();
}, 2000);
$state.go('app.podesenost_grilla', {}, {
reload: true
});
};