1

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

以下是事件发生的顺序:

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

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

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

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

这行得通,但代码很乱。我的问题是有没有更简单的方法来做到这一点?我可以抽象我的代码以便在我的控制器触发事件​​后触发它吗?而不必制作这个 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();
      }

    }

  };

});
4

2 回答 2

2

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

于 2012-08-12T18:03:40.937 回答
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_iddata-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; });

于 2012-11-16T15:12:14.833 回答