AngularJS:恢复模态取消时的形式?

时间:2014-08-21 21:08:50

标签: angularjs javascript-events angularjs-scope

我正在尝试在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处理事件之前调用的。我怎样才能避免这种竞争条件?

3 个答案:

答案 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的例子。它运作良好。