我一直在使用AngularJS中的指令,它使用从控制器的$ scope获取的数据构建一个HTML元素。我让我的控制器在从服务器获取JSON数据时设置了$ scope.ready = true变量。这样,每次获取数据时,指令都不必反复构建页面。
以下是发生事件的顺序:
控制器页面加载路径并触发控制器功能。
该页面扫描指令并触发此特定指令。
该指令构建元素并计算其表达式并继续前进,但是当指令链接函数被触发时,它等待控制器“准备好”。
准备好后,会触发一个内部函数,然后继续构建部分函数。
这样可行,但代码很乱。我的问题是,有更简单的方法吗?我可以抽象我的代码,以便在我的控制器触发事件后触发它吗?而不是必须使这个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();
}
}
};
});
答案 0 :(得分:2)
您可以在控制器中使用$scope.$emit
,在指令中使用$rootScope.on("bradcastEventName",...);
。好的一点是指令是分离的,你可以随时从项目中取出它。您可以为应用的所有指令和其他“正在运行”的组件重复使用相同的模式来响应此事件。
答案 1 :(得分:0)
我发现了两个问题:
$scope
变量并将数据实际应用于页面的绑定(当$ scope被消化时)之间存在差异。因此,如果您将数据设置为范围,然后触发事件以通知部分范围已准备就绪,那么这将无法确保该部分的数据绑定已准备就绪。所以为了解决这个问题,那么最好的解决方案就是:
使用此插件管理控制器与以下任何指令之间的事件处理: https://github.com/yearofmoo/AngularJS-Scope.onReady
不要将任何数据放入您希望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; });