AngularJS管理局部数据和控制器数据的更好方法

时间:2012-08-12 16:05:39

标签: angularjs

我一直在使用AngularJS中的指令,它使用从控制器的$ scope获取的数据构建一个HTML元素。我让我的控制器在从服务器获取JSON数据时设置了$ scope.ready = true变量。这样,每次获取数据时,指令都不必反复构建页面。

以下是发生事件的顺序:

  1. 控制器页面加载路径并触发控制器功能。

  2. 该页面扫描指令并触发此特定指令。

  3. 该指令构建元素并计算其表达式并继续前进,但是当指令链接函数被触发时,它等待控制器“准备好”。

  4. 准备好后,会触发一个内部函数,然后继续构建部分函数。

  5. 这样可行,但代码很乱。我的问题是,有更简单的方法吗?我可以抽象我的代码,以便在我的控制器触发事件​​后触发它吗?而不是必须使这个onReady内部方法。

    这就是它的样子(它的作品,但它很难测试):

    angular.module('App', []).directive('someDirective',function() {
    
      return {
    
        link : function($scope, element, attrs) {
    
          var onReady = function() {
            //now lets do the normal stuff
          };
    
          var readyKey = 'ready';
          if($scope[readyKey] != true) {
            $scope.$watch(readyKey, function() {
              if($scope[readyKey] == true) {
                onReady();
              }
            });
          }
          else {
            onReady();
          }
    
        }
    
      };
    
    });
    

2 个答案:

答案 0 :(得分:2)

您可以在控制器中使用$scope.$emit,在指令中使用$rootScope.on("bradcastEventName",...);。好的一点是指令是分离的,你可以随时从项目中取出它。您可以为应用的所有指令和其他“正在运行”的组件重复使用相同的模式来响应此事件。

答案 1 :(得分:0)

我发现了两个问题:

  • 在后台触发任何XHR请求都不会阻止加载模板。
  • 将数据应用于$scope变量并将数据实际应用于页面的绑定(当$ scope被消化时)之间存在差异。因此,如果您将数据设置为范围,然后触发事件以通知部分范围已准备就绪,那么这将无法确保该部分的数据绑定已准备就绪。

所以为了解决这个问题,那么最好的解决方案就是:

  1. 使用此插件管理控制器与以下任何指令之间的事件处理: https://github.com/yearofmoo/AngularJS-Scope.onReady

  2. 不要将任何数据放入您希望JavaScript函数可以拾取和使用的指令模板HTML中。因此,例如,如果您有一个如下所示的链接:

    <a data-user-id="{{ user_id }}" href="/path/to/:user_id/page">My Page</a>

    然后问题是该指令必须从:user_id属性准备data-user-id值,获取href值并替换数据。这意味着该指令必须不断检查data-user-id属性以查看它是否存在(通过每隔几刻检查一次attrs散列)。

    相反,将不同的范围变量直接放入URL

    <a href="/path/to/{{ directive_user_id }}/page">My Page</a>

    然后将其放在您的指令中:

      

    $ scope.whenReady(function(){     $ scope.directive_user_id = $ scope.user_id;    });