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

AngularJS: changing $rootScope variable doesn't change first selected option in ng-model

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

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

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

现在,当你 select 一些其他值时,它会将它存储在 $rootScope.proizvod 中,但稍后,在某些函数中,我想将 $rootScope.proizvod 重置回 '1 ' 而且它似乎不起作用。

我在这里错过了什么?

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

编辑:这是另一个功能:

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

upisPodataka 函数在单击按钮时被调用。

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

New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view, ng-include and ng-if all create new child scopes, so the problem often shows up when these directives are involved.

AngularJS Wiki - Understanding Scopes

如果 ng-model 在子范围内设置值。子作用域有自己的 属性,hides/shadows 父作用域 属性 同名。这不是 AngularJS 正在做的事情——这就是 JavaScript 原型继承的工作方式。阅读维基。

那么问题就变成了应该$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 exists, but it can be used for evil

Scopes in AngularJS form a hierarchy, prototypically inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.

Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject $rootScope and set values on it like any other scope. Since the scopes inherit from the root scope, these values will be available to the expressions attached to directives like ng-show just like values on your local $scope.

Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.

Conversely, don't create a service whose only purpose in life is to store and return bits of data.

— 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()可以在测试的时候使用