我正在尝试在ngModelController中使用AngularJS 1.3.0的新$rollbackViewValue()
方法取消对模式弹出窗体中的表单的更改,或者在关闭模式时将其保留。我正在为$modal
服务使用BootstrapUI。
我认为我走在正确的轨道上,但是有些东西不能正常运作:
在我的控制器中,我有:
$scope.updateCharge = function (charge) {
var scope = $scope.$new();
scope.charge = charge;
var modalInstance = $modal.open({
templateUrl: 'client/app/views/providers/charges/updateCharge.html',
scope: scope
});
modalInstance.result.then(function () {
scope.charge.$save({providerId: providerId, chargeId: charge.id});
});
};
在我的模板中,我有以下内容:
<form name="form" novalidate ng-model-options="{updateOn: 'save', debounce: {'save': 0 }}" class="form-horizontal" role="form">
<div class="modal-body">
<div class="form-group">
<label class="col-sm-3 control-label" for="chargeName">Name</label>
<div class="col-sm-9">
<input type="text" class="form-control" required ng-model="charge.code" id="chargeName"/>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-disabled="form.$invalid" ng-click="form.$broadcast('save'); $close()">Update</button>
<button class="btn btn-warning" ng-click="form.$rollbackViewValue(); $dismiss('cancel')">Cancel</button>
</div>
</form>
一般来说,这似乎有效。当我点击取消时,我的更改将被还原。当我点击Update时,模态会关闭,但我在scope.charge
对象中看不到我的更新。
我原本期望在模态结束之前更新我的scope.charge
对象。
我是否错误地使用了ng-model-options
?
如果我添加一个仅执行form.$broadcast('save')
的单独“应用”按钮,我会看到我的范围对象已正确更新。所以我假设我的$ close()是在ng-model-options
处理事件之前调用的。我怎样才能避免这种竞争条件?
答案 0 :(得分:4)
您可以使用$rollbackViewValue()
方法还原更改,但我认为这不是意图。
$ rollbackViewValue();取消更新并重置输入元素 阻止更新$ modelValue的值,这可能是由于 未决的去抖事件或因为输入正在等待一些事件 未来的事件。
如果您的输入使用ng-model-options设置去抖动 事件或事件,如模糊,你可以有一个情况 $ viewValue与ngModel不同步的时期 $ modelValue。
在这种情况下,如果您尝试更新,则可能会遇到困难 ngModel的$ modelValue在这些去抖/未来之前以编程方式进行 事件已经解决/发生,因为Angular的脏检查 机制无法判断模型是否实际发生了变化 或不。
之前应该调用$ rollbackViewValue()方法 以编程方式更改可能具有此类输入的输入模型 待处理的事件这对于确保输入很重要 将使用新模型值和任何待处理的字段更新字段 操作被取消。
正常用例是复制模型,可选择保留模型,如果一切正常,则刷新模型。
_this = this;
this.edit = function() {
this.modelToEdit = angular.copy(this.originalModel);
}
this.save = function () {
service.save(modelToEdit).then(function(savedModel) {
_this.originalModel = savedModel;
});
}
或者您可以backup
模型并在取消时恢复
_this = this;
this.edit = function() {
this.backupModel = angular.copy(originalModel);
}
this.cancel = function() {
this.originalModel = this.backupModel;
}
this.save = function() {
service.save(this.originalModel).then(function(data) {}, function(error) {
_this.originalModel = _this.backupModel;})
}
答案 1 :(得分:0)
我可以看到您的代码存在一些问题:
ngModelOptions.updatedOn
意为DOM event,即点击,模糊,鼠标中心,鼠标悬停等,$broadcast
方法,所以它永远不会发出事件。我认为它有效的事实是因为type="button"
上没有<button>
所以它们在表单中被视为"submit"
。因此,模型会更新。
我建议您使用简化版本,
ng-model-options
。type="submit"
,然后移除form.$broadcast
type="button"
。我不确定它如何与模态一起使用,但这里有一个ng-if
的傻瓜:http://plnkr.co/edit/m37Fd0NybpnfslNkvJnO
答案 2 :(得分:0)
我最终没有使用任何建议作为答案的选项,因为现实是,角度1x没有“正确”的方式来做我想要的。 Angular使用2way绑定,是的,我可以编写花哨的指令,使生活更轻松,但事实上它只是让html看起来更复杂。
我按照建议的方式确定了论坛上的许多主题,即使用angular.copy然后在你的html中使用克隆模型。提交更改时,请将克隆的模型设置为原始模型。
这里有很多关于如何使用angular.copy的例子。它运作良好。