Angularjs 在没有超时函数的情况下,如何克服指令内的竞争条件?
我正在尝试创建一个指令。事情根本不起作用,所以我简化了事情,直到我发现这个基本的比赛条件问题给我带来了问题。在我的指令控制器中,我需要做一些检查,如Angularjs 在没有超时函数的情况下,如何克服指令内的竞争条件?,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我正在尝试创建一个指令。事情根本不起作用,所以我简化了事情,直到我发现这个基本的比赛条件问题给我带来了问题。在我的指令控制器中,我需要做一些检查,如 if ($scope.test.someValue === true) { $scope.test.anotherValue += 1; } 下面是我的基本指令和一些日志,以说明这个问题是如何表现出来的 app.directive('myDirective', function () { return { restrict
if ($scope.test.someValue === true) { $scope.test.anotherValue += 1; }
下面是我的基本指令和一些日志,以说明这个问题是如何表现出来的
app.directive('myDirective', function () {
return {
restrict: 'E',
replace: true,
scope: {
test: '='
},
template: '<div><pre>{{ test | json }}</pre></div>',
controller: function ($scope, $timeout) {
// this logs undefined
console.log($scope.test);
// this logs the scope bound 'test' object
$timeout(function() {
console.log($scope.test);
}, 300);
}
};
});
app.directive('myDirective',函数(){
返回{
限制:'E',
替换:正确,
范围:{
测试:'='
},
模板:“{test | json}}”,
控制器:函数($scope,$timeout){
//此日志未定义
log($scope.test);
//这将记录范围绑定的“测试”对象
$timeout(函数(){
log($scope.test);
}, 300);
}
};
});
在这种比赛条件下,正确的工作方式是什么?我担心在现实世界中,此超时函数会根据api调用所需的时间而工作或失败。请记住,在“链接”阶段(分配控制器时),尚未分配$scope.test
变量-因此未定义
$timeout(fn,timeout)
是一种执行将影响$scope中某些内容的方法。您可以将$timeout()值设置为0,它仍然可以工作。这是因为$timeout(…)函数将延迟到当前$digest()
周期之后
参考文献:
此外,如果要查看特定值的更改,可以执行以下操作:
$scope.$watch('test', function(val){
if(val != undefined) {
if ($scope.test.someValue === true) { $scope.test.anotherValue += 1; }
}
})
处理竞争条件的一种方法是使用您想要使用的变量,当其值更改为您想要的值时(!=undefined
,在您的情况下),您可以使用该变量。每个$digest
周期对需要监视的表达式求值。以下是您案例的一个示例:
app.directive('myDirective', function () {
return {
restrict: 'E',
replace: true,
scope: {
test: '='
},
template: '<div><pre ng-click="someFunc()">{{ test | json }}</pre></div>',
controller: function ($scope) {
/* No two-way bindings yet: test -> undefined */
/* Business logic can go here */
$scope.someFunc = function () {
alert('I implement the business logic !');
};
},
link: function postLink(scope, elem, attrs) {
/* Bindings are in place. Safe to check up on test. */
console.log($scope.test);
}
};
});
控制器在预链接阶段实例化(当指令的作用域尚未绑定到任何父作用域时)
控制器是放置指令的业务逻辑的地方
任何初始化代码(特别是依赖于父范围绑定的代码)都应该在链接阶段运行(即使用指令定义对象的link
属性)
app.directive('myDirective',函数(){
返回{
限制:'E',
替换:正确,
范围:{
测试:'='
},
模板:“{test | json}}”,
控制器:功能($scope){
/*还没有双向绑定:测试->未定义*/
/*业务逻辑可以放在这里*/
$scope.someFunc=函数(){
警报(“我实现了业务逻辑!”);
};
},
链接:函数postLink(范围、元素、属性){
/*绑定到位。测试时可以安全检查*/
log($scope.test);
}
};
});
这很有道理。从link函数设置控制器值是否简单?例如,基于您上面的示例。如果控制器包含$scope.someConstant=null;然后,我是否可以在链接函数$scope.someConstant=$scope.test.someProperty;中包含该值,从而在链接函数初始化时更新该值?或者这两个函数之间的通信是如何工作的?是的,注入控制器的$scope
和传递给链接函数的scope
参数是相同的。更新一个位置的值也会更新另一个位置的值(因为它是同一个对象)。@Constellates:我不是故意的!@#$%,但公认的答案不是“在这种比赛条件下正确的工作方式”。(并不是说我很在乎——只是说……)不用担心,我对定制指令还是新手,所以我不能总是解读什么是最佳实践。虽然我仍然有相同的种族问题与你的解决方案。链接函数中的console.log未定义日志记录。如果我把它放在$scope中。$watch在link函数中,它会再次工作。@Constellates:也许我搞错了什么,因为它似乎是。不过,你的意思可能有所不同。
app.directive('myDirective', function () {
return {
restrict: 'E',
replace: true,
scope: {
test: '='
},
template: '<div><pre ng-click="someFunc()">{{ test | json }}</pre></div>',
controller: function ($scope) {
/* No two-way bindings yet: test -> undefined */
/* Business logic can go here */
$scope.someFunc = function () {
alert('I implement the business logic !');
};
},
link: function postLink(scope, elem, attrs) {
/* Bindings are in place. Safe to check up on test. */
console.log($scope.test);
}
};
});