【发布时间】:2013-12-27 00:00:37
【问题描述】:
我有一个注入提供程序的指令(带有私有变量) - 下面和http://jsfiddle.net/jycchoong/BmaQD/3/ 中的示例代码。当 (a) 在指令的链接函数中内联调用它的方法,或 (b) 通过在指令的链接函数中调用的 $broadcast 时,注入的提供程序是预期的。但是,当 (c) 通过 $timeout 调用它时(或者在我的代码的情况下,在 AJAX 调用弄脏被监视对象之后的 $watch),注入的提供程序与指令的最后实例化相关联。
您可以看到 (c) 出现在输出中(第一行,第三句)。而在 (a) 或 (b) 中(输出中的前两个句子),从提供者返回“实例 1”,对于 (c),返回“实例 2”。 $scope 本身是正确的(请参阅输出中的 $scope.$id,因此我们处于正确的指令实例中),但提供程序实例用于最后一个指令。
对于我做错了什么或者我应该以不同的方式构建代码有什么建议吗?有关我所追求的模式的更广泛解释(您不必阅读),请查看下面代码片段之后的背景说明,如果有关于实现总体目标的不同方法的建议。
感谢您的帮助!!!
附言。这不是关闭问题。所有场景 (a)、(b) 和 (c) 在日志函数中具有相同的本地/闭包可见性。
HTML:
<div my-directive id="Instance 1"></div>
<div my-directive id="Instance 2"></div>
JS:
var app = angular.module('app', ['myModule']);
angular.module('myModule',[])
.directive('myDirective', function (myProvider, $timeout) {
return {
restrict: 'A',
scope: true,
link: function ($scope, element) {
element.text('');
var log = function ($event, eventData) {
element.text(element.text()+'For source "'+($event ? eventData.source : 'Inline')
+ '", scope id = ' + $scope.$id + ' with provider "' + myProvider.externalFn()
+ '". ');
};
myProvider.init(element.attr('id'));
// Inline
log();
$scope.$on('myEvent', log);
// Invoke broadcast inline
$scope.$broadcast('myEvent', {source: 'Broadcast Inline'});
$timeout(function() {
// Invoke broadcast in $timeout or from $watch
$scope.$broadcast('myEvent', {source: 'Broadcast Delayed'});
}, 1000, false);
}
};
})
.provider('myProvider', function () {
var internalVar;
return {
$get: function () {
return {
init: function (value) {
internalVar = value;
},
externalFn: function () {
return internalVar;
}
};
}
};
});
输出:
For source "Inline", scope id = 003 with provider "Instance 1". For source "Broadcast Inline", scope id = 003 with provider "Instance 1". For source "Broadcast Delayed", scope id = 003 with provider "Instance 2".
For source "Inline", scope id = 004 with provider "Instance 2". For source "Broadcast Inline", scope id = 004 with provider "Instance 2". For source "Broadcast Delayed", scope id = 004 with provider "Instance 2".
背景
我希望做的事情并不是那么不寻常。我将指令代码和提供程序代码分开。我选择提供者是因为服务需要能够存储自己的私有变量,并且提供者/指令组合的每个实例在私有变量中都有不同的值。这允许不同的开发人员处理服务与指令(或允许注入特定服务的不同变体)。一切都很好,直到我不得不从 AJAX 调用中更新我的数据,突然之间,注入的提供程序不再是我所期望的。
一个明显的解决方法是将 $scope 传递给提供程序 - 正如您在上面的代码中所看到的,正确的 $scope 是可用的。这有点丑陋,破坏了模式的好处。我当然不希望提供程序开发人员摆弄整个 $scope。另一种解决方案是创建一个 $scope.myProvider 对象,然后只将它传递给提供程序以使用(并将所有内容存储在其中),以便 $scope 的其余部分不可见,但这似乎有点像破解。
欢迎评论...
【问题讨论】:
标签: angularjs angularjs-service