Javascript AngularJS:更改$rootScope变量不会更改ng模型中的第一个选定选项

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';到

我有一个我似乎无法解决的具体问题

在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';到$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
      });
};