我正在使用angularjs开发一个应用程序,我也在使用指令,因为某些UI在多个页面上重复使用。当我有一个依赖于承诺值的指令时,我必须使用 $scope.$watch 和一个 if 条件来检查未定义,因为指令在承诺完成之前编译。下面是一个示例:
myAppModule.directive('topicDropdown', function () {
return {
templateUrl: 'Scripts/app/shared/dropdown/tmplTopic.html',
restrict: 'AE',
scope: {
subjectId: '=',
setDefault: '=',
topicId: '='
},
controller: [
'$scope', 'service', function ($scope, service) {
$scope.$watch('subjectId', function () {
if ($scope.subjectId != undefined)
$scope.getTopics();
});
$scope.getTopics = function () {
service.get("section/topics/" + $scope.subjectId).then(function (data) {
$scope.listOfTopics = data;
if ($scope.setDefault) {
$scope.subjectId = $scope.listOfTopics[0].UniqueId;
}
});
}
}
]
}
});
subjectId 最终将来自一个承诺,但没有$watch我将得到一个未定义的错误,因为它将在没有 ID 的情况下触发 getTopics。
scope: {
subjectId: '=',
setDefault: '=',
topicId: '='
},
目前,这段代码可以工作,但我必须在每次 subjectId 更改时调用摘要循环,这将遍历范围正在监视的所有内容。我只关心此时主题ID何时更改。
我还看到了一些将ng-if用于模板html的建议。像这样:
<div ng-if="subjectId != undefined">
<topic-dropdown subject-id="subjectId"></topic-dropdown>
</div>
有了这个,我不必使用 $scope.$watch 但是我不确定这是否是最好的方法。
有没有人有解决这个问题的好方法?是否有任何我不知道的指令属性?
缺口
为 subjectId 传递一个承诺,并getTopics
等待它解析。它看起来像这样:
$scope.getTopics = function () {
$scope.subjectIdPromise.then(function (subjectId) {
$scope.subjectIdPromise = service.get("section/topics/" + subjectId)
.then(function (data) {
$scope.listOfTopics = data;
if ($scope.setDefault) {
return data[0].UniqueId;
} else { return subjectId; }
});
});
};
这样做的方式是对subjectId
的所有访问都是在then
成功函数中完成的。如果您想更改subjectId
请用新承诺替换承诺。
尝试使用承诺模式,
myAppModule.directive('topicDropdown', function () {
return {
templateUrl: 'Scripts/app/shared/dropdown/tmplTopic.html',
restrict: 'AE',
scope: {
subjectId: '=',
setDefault: '=',
topicId: '='
},
controller: [
'$scope', 'service', function ($scope, service) {
$q.when($scope.subjectId).then(
service.get("section/topics/" + $scope.subjectId).then(function (data) {
$scope.listOfTopics = data;
if ($scope.setDefault) {
$scope.subjectId = $scope.listOfTopics[0].UniqueId;
}
});
)
]
}
});
OR
myAppModule.directive('topicDropdown', function ($q) {
return {
templateUrl: 'Scripts/app/shared/dropdown/tmplTopic.html',
restrict: 'AE',
scope: {
subjectId: '=',
setDefault: '=',
topicId: '='
},
link: function(scope, element, attrs){
$q.when(subjectId).then(
service.get("section/topics/" + scope.subjectId).then(function (data) {
scope.listOfTopics = data;
if (scope.setDefault) {
scope.subjectId = scope.listOfTopics[0].UniqueId;
}
});
)
}
}
});
但我认为您将以一种或另一种方式使用$watch。使用$watch不会伤害任何东西,它的角度方式可以保持事物的连接。