AngularJS:更改$ rootScope变量并不会更改ng-model中的第一个选定选项

时间:2017-03-11 14:18:23

标签: 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';

因此,首次加载页面时,会选择第一个选项。如果我将$rootScope.proizvod = '1';更改为$rootScope.proizvod = '3';它将加载第三个选项。

现在,当您选择其他值时,它会将其存储在$rootScope.proizvod中,但稍后,在某些功能中,我想将$rootScope.proizvod重置为&#39; 1&#39;它似乎没有起作用。

我在这里缺少什么?

P.S。如果没有$parent.proizvod,我的选择甚至不会更改$rootScope.proizvod值。

编辑:这是另一个功能:

$rootScope.upisPodataka = function() {
      setTimeout(function () {
      $rootScope.proizvod = '1';
      $scope.$apply();
       }, 2000);
      $state.go('app.podesenost_grilla', {}, {
        reload: true
      });
只需点击一下按钮即可调用

upisPodataka函数。

1 个答案:

答案 0 :(得分:1)

使用ng-model='$parent.proizvod'并不保证在所有情况下都更新$rootScope

  

新的AngularJS开发人员通常没有意识到ng-repeatng-switchng-viewng-includeng-if都会创建新的子范围,因此问题经常出现在涉及这些指令时显示。

     

- AngularJS Wiki - Understanding Scopes

如果ng-model设置子范围中的值。子作用域获取其自己的属性,该属性隐藏/隐藏同名的父属性。这不是AngularJS正在做的事情 - 这就是JavaScript原型继承的工作原理。阅读Wiki。

所以问题应该变成$parent.$parent.proizvod吗?或者也许$parent.$parent.$parent.proizvod?通过反复试验来做到这一点?

更强大的方法是使用ng-change directive来更新变量。

<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);
});

请考虑使用custom service来存储变量,而不是使用$rootScope

  

$rootScope存在,但它可以用于邪恶

     

AngularJS中的作用域形成一个层次结构,原型继承自树顶部的根作用域。通常这可以忽略,因为大多数视图都有自己的控制器,因此也有范围。

     

有时,您希望为整个应用程序提供全局数据。对于这些,您可以注入$rootScope并在其上设置值,就像任何其他范围一样。由于范围继承自根范围,因此这些值可用于附加到ng-show等指令的表达式,就像本地$ scope上的值一样。

     

当然,全局状态很糟糕,你应该谨慎使用$rootScope,就像你希望用任何语言的全局变量一样。特别是,不要将它用于代码,仅用于数据。如果您想在$rootScope上添加一项功能,那么将其放入可以在需要的地方注入并且更容易测试的服务几乎总是更好。< / p>      

相反,不要创建一项服务,其唯一目的就是存储和返回数据位。

     

— AngularJS FAQ

使用$ timeout而不是window.setTimeout

$rootScope.upisPodataka = function() {
      //setTimeout(function () {
      $timeout(function () {
         $rootScope.proizvod = '1';
         //$scope.$apply();
      }, 2000);
      $state.go('app.podesenost_grilla', {}, {
        reload: true
      });
};

$timeout service换行windows.setTimeout并将其与AngularJS框架及其摘要周期集成。然后不需要$apply()

此外,测试时可以使用$timeout.flush()