AngularJS是管理分区和控制器数据的更好方法

AngularJS是管理分区和控制器数据的更好方法,angularjs,Angularjs,我一直在使用AngularJS中的指令,它使用从控制器的$scope中获取的数据构建HTML元素。当控制器从服务器获取JSON数据时,我让它设置一个$scope.ready=true变量。这样,指令就不必在每次获取数据时反复构建页面 以下是事件发生的顺序: 控制器页面加载路由并启动控制器功能 页面扫描指令,并触发此特定指令 指令构建元素并计算其表达式并继续,但当指令链接函数被激发时,它会等待控制器“就绪” 准备好后,将启动一个内部函数,然后继续构建分部 这是可行的,但代码很混乱。我的问题是有没有

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

以下是事件发生的顺序:

  • 控制器页面加载路由并启动控制器功能

  • 页面扫描指令,并触发此特定指令

  • 指令构建元素并计算其表达式并继续,但当指令链接函数被激发时,它会等待控制器“就绪”

  • 准备好后,将启动一个内部函数,然后继续构建分部

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

    下面是它的外观(它工作正常,但很难测试):


    您可以在控制器中使用
    $scope.$emit
    $rootScope.on(“bradcastEventName”,…)在指令中。好的一点是,该指令是解耦的,您可以随时将其从项目中拉出。您可以对应用程序的所有指令和其他“正在运行”组件重复使用相同的模式来响应此事件。

    我发现了两个问题:

    • 在后台触发任何XHR请求都不会阻止加载模板
    • 将数据应用于
      $scope
      变量与实际将该数据应用于页面绑定(当对$scope进行摘要处理时)之间存在差异。因此,如果您将数据设置为作用域,然后触发一个事件,通知该分部作用域已就绪,那么这将无法确保该分部的数据绑定已就绪
    因此,要解决这个问题,最好的解决方案是:

  • 使用此插件管理控制器和以下任何指令之间的事件处理:

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

    然后问题是指令必须从
    数据用户id
    属性中准备
    :user_id
    值,获取href值并替换数据。这意味着指令必须连续检查
    数据用户id
    属性,以查看它是否存在(每隔几分钟检查一次attrs散列)

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

    然后将其放在指令中:

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


  • 我得到了$rootScope,但是当我从控制器$scope中激发$emit时,它就不会拾取它了?有什么想法吗?结果证明它是可行的,但是控制器代码运行得更快,并且在指令有机会设置$on事件之前执行和发出响应。你知道怎么解决这个问题吗?我明白了,如果你试着用延迟和承诺($q)。现在不再从控制器中公开值,而是公开“promise”,您可以稍后在指令中使用它,如
    $scope.promise.then(…),无论如何,若我并没有错的话,你们的指令在视图中使用,视图由你们提到的控制器控制。请记住,在这种情况下,angularjs首先安装控制器,然后编译(如果以前没有编译)您的视图。编译完成后,它将调用您指令中的then link方法。顺便说一句,如果您的事件顺序需要符合您所述的顺序,您不必担心控制器是否准备就绪,只需
    $scope.$watch(“name”,function(){})
    ,您的指令将捕获下一个更改,在链接时,请尝试读取$scope.something,即使它未定义。您是否可以在JSFIDLE中提供给我?
    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();
          }
    
        }
    
      };
    
    });