【问题标题】:Boolean variables in Angular with ng-show, not being set initiallyAngular中带有ng-show的布尔变量,最初没有设置
【发布时间】:2016-12-01 14:07:12
【问题描述】:

对于特定的下拉菜单,我想根据我的应用中的布尔值显示不同的选项。我已经设置了一切并且 SORTA 工作正常,但是 DOM 没有正确更新以显示下拉列表中的值。我用来检查代码的console.logs 输出了我的变量的正确值,当我刷新页面时,下拉列表填充得很好。

$scope.login = function () {
    var loginUrl = url;

    $server.post(loginUrl, $scope.user)
        .then(function(response) {
            var data = response.data;

            if(data.status == 'OK') {
                //some things here that work fine
                $scope.getRights();
            } else {
                $scope.user.password = '';
            }
        }
};

$scope.getRights = function() {
    console.log("yo");
    $scope.boolA = false;
    $scope.boolB = false;
    $scope.boolC = false;
    $scope.boolD = false;

    $scope.permissions.forEach(function (right) {
        console.log(right);
        switch(right) {
            case "A":
                $scope.boolA = true;
                break;
            case "B":
                $scope.boolB = true;
                break;
            case "C":
                $scope.boolC = true;
                break;
            case "D":
                $scope.boolD = true;
                break;
        }
    });
    console.log($scope.boolA + " " + $scope.boolB + " " + $scope.boolC + " " + $scope.boolD);
};

使用匹配的 html,正确的控制器在上面的 <div> 中定义。

<ul class="dropdown-menu" uib-dropdown-menu role="menu">
    <li role="menuitem" ng-show="boolA"><a href="#/start">
        Option A
    </a></li>
    <li role="menuitem" ng-show="boolB"><a href>
        Option B
    </a></li>
    <li role="menuitem" ng-show="boolC"><a href>
        Option C
    </a></li>
    <li role="menuitem" ng-show="boolD"><a href>
        Option D
    </a></li>
</ul>

$scope.permissions 中的json是["A","B","D"]

我的 console.log 输出:true true false true

如果我在浏览器中检查 $scope 变量,它们没有设置,并且下拉选项都启用了 ng-hide。当我刷新页面时,它们会显示在 $scope 检查器中,并且我的下拉列表具有正确的值。所以看起来要么存在同步/异步问题,要么我使用了不正确的路由来设置这些变量。

简单地将它们设为全局并不会改变任何东西。一个“简单”的修复方法是在成功登录后强制重新加载,但这并不像“角度方式”。我很确定我只是在这里犯了一个初学者的错误。谁能帮我找出这个错误在哪里?

【问题讨论】:

  • 我认为这可能是范围继承的问题。您可以使用chrome.google.com/webstore/detail/angularjs-batarang/…chrome.google.com/webstore/detail/ng-inspector-for-angularj/… 调试您的范围树,并确保相同的对象持有这些值。
  • 可能是......当我使用干净的缓存登录时,所有布尔值都不存在 - 或者当我全局定义它们时设置为 false - 并保持这种状态。只有在我真正刷新页面后,它们才会更改为正确的值。这不是由于范围继承,是吗?我在同一个控制器中定义和设置它们...
  • 您是否尝试过隔离此问题?也许尝试在您自己的 plunkr 中重现它,同时使用相同的设置(发出发布请求并在其后填写 boolX 属性)?
  • @kablam 不,如果是继承问题,它将创建新对象。您的范围树看起来如何?你有机会使用 chrome 扩展吗?
  • @FilipeSilva:我会试试的,谢谢。

标签: angularjs


【解决方案1】:

您是否可以不简单地将“权限”数组转换为菜单项列表,而不是这样做?这样用户将无法看到 html 中的选项。

$scope.getRights = function() {
$scope.permissions = ["A", "B", "D"];
$scope.menuItems = [];
$scope.permissions.forEach(function(val) {
  $scope.menuItems.push({
    title: val
  });
});

}

<ul role="menu">
<li role="menuitem" ng-repeat="item in menuItems">
  <a>Option {{item.title}}</a>
</li>

查看this plunkr

更新

在这种情况下,您的 DOM 很可能没有更新,因为与 this post 相关的问题建议使用 $apply():

$scope.$apply(function(){
        $scope.boolA = false;
    });

另外,请务必查看Danny Bullis 评论:

使用 $q.defer();返回的对象允许您在异步方法完成后调用 .resolve() 或 .reject() 方法。 $q.defer() 对象的 resolve 和 reject 方法都在解析异步方法后在内部调用 $digest。 $digest 告诉 Angular 重新评估您的 $scope 属性,这将满足您的需求。这是一个更好的做法。如果您不需要调用 $apply() 并且有更好的内置角度机制来处理这个问题,请避免调用。

【讨论】:

  • 这是一个有趣的观点……值得研究。除了我想要的是能够引用其他页面上的不同权限,例如禁用表单的某些部分。因此,即使我可以使用这种方式完全隐藏选项,我仍然希望定义布尔值以供以后使用。
  • 更新后:当我尝试使用 $apply() 或 $digest() 时,我收到一条错误消息 $apply already in progress。当我使用 $timeout (我发现它也返回一个承诺)时,我在页面加载和超时结束后得到了 console.log 检查,但我的布尔值中仍然没有值。当我刷新页面时,一旦超时,就会设置变量并填充菜单。它必须是别的东西......
猜你喜欢
  • 2023-04-07
  • 1970-01-01
  • 2017-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多