我创建了一个 confirmationDialogHeader
指令,其使用方式如下:
<ul>
<li ng-repeat="item in items">
{{item}}
<button class="btn btn-mini"
confirmation-dialog-header="Delete Item"
confirmation-dialog-action="deleteItem($index)">
Delete
</button>
</li>
</ul>
当单击按钮时,应该打开一个确认对话框,如果用户确认,则应该调用deleteItem($index)
,并关闭对话框。
我的问题是最后一点:关闭对话框。
这是 Controller (CoffeeScript):
app.controller 'AppCtrl', ['$scope', '$q', '$timeout', ($scope, $q, $timeout) ->
$scope.items = ['Item 1', 'Item 2']
$scope.deleteItem = (index) ->
deferred = $q.defer()
$timeout ->
$scope.items.splice(index, 1) # All good if this line is removed
deferred.resolve()
, 1000
deferred.promise
]
这是指令:
app.directive 'confirmationDialogHeader', ['$compile', '$q', ($compile, $q) ->
restrict: 'A'
scope:
confirmationDialogAction: '@'
controller: ($scope) ->
$scope.onConfirm = ->
$scope.$parent.$eval($scope.confirmationDialogAction).then ->
$scope.confirmationDialog = off # Why this doesn't close the dialog?
link: (scope, element, attrs) ->
$confirmationDialog = $ """
<div modal="confirmationDialog">
<div class="modal-header">
<h4>#{attrs.confirmationDialogHeader}</h4>
</div>
<div class="modal-body">
Are you sure?
</div>
<div class="modal-footer">
<button class="btn" ng-click="confirmationDialog = false">
Cancel
</button>
<button class="btn" ng-click="onConfirm()">
Yes
</button>
</div>
</div>
"""
$(document.body).append($confirmationDialog)
$compile($confirmationDialog)(scope)
$(element).click ->
scope.$apply ->
scope.confirmationDialog = yes
]
As you can see ,在 deleteItem()
完成并执行 $scope.confirmationDialog = off
后,对话框未关闭。
有趣的是,如果 $scope.items.splice(index, 1)
用 $timeout
包装,则对话框是 正确关闭!
$timeout ->
$scope.items.splice(index, 1)
为什么这里需要这个 $timeout
包装?
是否有任何关于何时应该使用 $timeout
包装代码的指南?
Working version of this directive that uses $dialog
.
最佳答案
Are there any guidelines about when should we wrap code with $timeout?
$timeout 用作 native setTimeout 的替代品。相对于 native 超时的优点是它在 try/catch block 中运行回调,并且发生的任何错误都将转发到您的应用程序的异常处理程序服务。
但是,从我玩你的演示来看,这不是我看到的问题,并且代码可以简化。
更新 我希望使用模式对话框来实现您的具体实现,但我没有太多运气。因此使用 $dialog 服务而不是模态指令来实现它。也许会有帮助 - here it is
此外,在您的原始版本中,我发现当您单击"is"关闭对话框时,范围正在更新,并且它发生在摘要内,因此它应该触发任何观察程序,从而关闭对话框。在这方面,我看不出它在我的浏览器中因任何原因而不起作用的原因,无论是否使用超时都没有区别。
关于AngularJS:为什么以及何时需要调用 $timeout?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17025321/