【问题标题】:Wait until scope variable is loaded before using it in the view in angular.js等到作用域变量被加载后再在 angular.js 的视图中使用它
【发布时间】:2013-05-13 02:33:49
【问题描述】:

我见过thisthis,但似乎有更简单的方法。

在我看来,我有几个通过权限控制的菜单选项 - 即,不是每个人都可以看到“仪表板”视图。因此,在我看来,在我的菜单选项中,我有以下内容:

<li ng-show="validatePermission('Dashboard')">Dashboard</li>

在我的控制器中,我定义了一个 validatePermission 方法,它正在查看当前用户的权限。例如:

  $scope.validatePermission = function(objectName) {
    if $scope.allPermissions......

另外,在我的控制器中,我正在通过 $http 调用加载这些权限:

  $http.get('permissions/' + userid + '.json').success(function(data) {  
    $scope.allPermissions = data;....

问题是 $scope.allPermissions 在视图调用 validatePermission 之前没有被加载。如何在视图呈现之前等待加载 allPermissions?

【问题讨论】:

    标签: angularjs promise


    【解决方案1】:

    你问:

    如何在视图呈现之前等待加载所有权限?

    要防止整个视图呈现,您必须使用解析。不过你不必使用 promise 库,因为 $http 返回一个 promise:

    var app = angular.module('app');
    
    app.config(function ($routeProvider) { 
      $routeProvider
        .when('/', {
            templateUrl : 'template.html',
            controller : 'MyCtrl',
            resolve : MyCtrl.resolve
      });
    });
    
    function MyCtrl ($scope, myHttpResponse) {
       // controller logic
    }
    
    MyCtrl.resolve = {
      myHttpResponse : function($http) {
        return $http({
            method: 'GET',
            url: 'http://example.com'
        })
        .success(function(data, status) {
            // Probably no need to do anything here.
        })
        .error(function(data, status){
            // Maybe add an error message to a service here.
            // In this case your $http promise was rejected automatically and the view won't render.
        });
      }
    }
    

    但是,如果您只是想隐藏仪表板

  • ,请按照 Joe Gauterin 的建议进行操作。如果您需要,这里有一个非常简单的example plunkr
  • 【讨论】:

      【解决方案2】:

      allPermissions 尚未加载时,让 validatedPermission 函数返回 false。这样,在加载 allPermissions 之前,不会显示带有 ng-show 的元素。

      或者,将ng-show="allPermissions" 放在封闭的&lt;ul&gt;&lt;ol&gt; 上。

      【讨论】:

      • 谢谢。这是否意味着 validatePermissions 函数将被多次调用?即,可能最初当 allPermissions 未加载时,它真的会在加载后再次调用它。它怎么知道再次调用它(加载后)?不会只调用一次吗?
      • 我之所以选择这个,是因为它看起来最简单且有效——尽管我不能 100% 确定原因。我猜 Angular 最初会在显示视图时调用 validatePermissions 函数,即使 allPermissions 未加载(并且我返回 false),它也会在加载 allPermissions 时再次调用该函数 - 不知何故知道再次调用此函数。
      • @ArthurFrankel - 是的,ng-watch 中的表达式将在每个周期计算一次。 Angular 作为一个整体是这样工作的——ng-show 不是“显示表达式是否为真”,它是“显示 while 表达式为真”。如果您确实需要在加载权限之前进行处理,那么其他选项很好,但据我所知,您不在这里。
      • 回复。 '它怎么知道再次调用它' - ng-show 指令监视表达式的值,并且 $http 服务导致在收到对 http 请求的响应后评估所有相关监视。这个话题太复杂了,无法在评论中详细介绍。
      • 哦,伙计...我已经解决这个问题小时了。这既优雅又简单;这可能就是为什么我没有自己解决它的原因。 =]
      【解决方案3】:

      您还可以在路由控制器上指定一个解析对象,该对象将在渲染该路由之前等待该对象解析。

      来自角度文档:https://docs.angularjs.org/api/ngRoute/provider/$routeProvider

      resolve - {Object.=} - 应注入控制器的可选依赖映射。如果这些依赖项中的任何一个是承诺,它们将在控制器被实例化并触发 $routeChangeSuccess 事件之前被解析并转换为一个值。地图对象是:

      key – {string}:要注入控制器的依赖项的名称。 factory - {string|function}:如果是字符串,那么它是服务的别名。否则,如果是函数,则将其注入并将返回值视为依赖项。如果结果是一个promise,它会在其值被注入控制器之前被解析。

      还有一个 google 组参考:https://groups.google.com/forum/#!topic/angular/QtO8QoxSjYw

      【讨论】:

        【解决方案4】:

        我也遇到过类似的情况,你可能也想快速看看

        http://docs.angularjs.org/api/ng/directive/ngCloak

        如果您仍然看到“闪烁”效果。

        根据 angularjs 文档:

        ngCloak 指令用于防止 Angular html 模板在加载应用程序时被浏览器以原始(未编译)形式短暂显示。使用该指令可以避免 html 模板显示引起的不良闪烁效果。

        【讨论】:

        • 欢迎来到 Stack Overflow!虽然这在理论上可以回答问题,it would be preferable 在此处包含答案的基本部分,并提供链接以供参考。
        • ng-cloak 过去曾帮助我解决完全相同的情况
        【解决方案5】:

        将代码包装在 ng-if 中为我解决了这个问题:

        <div ng-if="dependentObject">
          <!-- code for dependentObject goes here -->
        </div>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-07-07
          • 2013-01-23
          • 1970-01-01
          • 2023-04-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多