AngularJS - 重置绑定对象的状态

时间:2015-04-05 22:01:48

标签: angularjs angular-ui

我已经对一些书籍进行了非常简单的重复,当用户点击该书时,它会打开一个新的模态。他们可以在哪里编辑这本书。由于我使用双向绑定,因此显示页面为'当我在模态上键入时自动更改 - 这很棒。

但是,我想要做的是让用户按下取消按钮,书的状态会恢复到更改之前的状态。这可能在Angular中没有返回并重置整个$ scope.books对象吗?

在实际应用程序中,这将是一个API调用,除非完全必要,否则我不会再拨打另一个服务器。是否有一种模式可以解决这个问题?

(function(){
    var app = angular.module('ngModalDemo', ['ui.bootstrap']) 
    .controller('formController', function($scope, $modal, $log){

        $scope.books = [
            { Id: 1, Name:'A Feast For Crows'},
            { Id: 2, Name:'Before they are Hanged'}
        ];

        $scope.openModal = function (currentBook) {             
            var modalInstance = $modal.open({
                templateUrl: 'SomeModal.html',
                controller: [
                    '$scope', '$modalInstance', function($scope, $modalInstance){
                        $scope.editBook = currentBook;
                        $scope.saveModal = function (book) {
                            $modalInstance.close();
                        };
                        $scope.cancelModal = function () {
                            //  Restore the previous state here!
                            $modalInstance.close();
                        };
                    }]
            });
        };
    })
})();

<div ng-controller="formController">

    <p ng-repeat="displayBook in books">
         <a href="#" ng-click="openModal(displayBook)">{{displayBook.Name}}</a>
    </p>    

    <script type="text/ng-template" id="SomeModal.html">
        <form name="editForm" ng-submit="saveModal(editBook)" noValidate>
            <div class="modal-header">
                Name: <input ng-model="editBook.Name" required /><br />
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-warning" ng-click="cancelModal()">Cancel</button>
                <button class="btn btn-info" ng-disabled="editForm.$dirty && editForm.$invalid">Save</button>
            </div>
        </form> 
    </script>
</div>

3 个答案:

答案 0 :(得分:3)

您可以创建对象的深层副本到temp,然后在必要时将其设置回来:

var temp = angular.copy(currentBook);
$scope.editBook = currentBook;
$scope.saveModal = function (book) {
    $modalInstance.close();
};
$scope.cancelModal = function () {
    //  Restore the previous state here!
    angular.copy(temp, $scope.editBook);
    $modalInstance.close();
};

答案 1 :(得分:3)

Angular有方法copy,可以通过克隆对象或数组来为你创造工作。

我们的想法是将数据的 copy 传递给模态而不是实例本身。因此,当用户按Cancel时,主实例不会更改。

在你的情况下:

$scope.editBook = currentBook;

写:

$scope.editBook = angular.copy(currentBook);

答案 2 :(得分:2)

在显示模态之前考虑缓存原始模型的副本,然后在用户取消时重置它。这可以直接在JavaScript中轻松完成,或者您可以选择使用Angular的$cacheFactory来处理更复杂的情况。

例如,您可以为ng-repeat添加索引:

<p ng-repeat="displayBook in books track by $index">
     <a href="#" ng-click="openModal(displayBook, $index)">
          {{displayBook.Name}}
     </a>
</p>

如果用户取消模式,则更改控制器方法以重置$scope.books集合:

$scope.openModal = function (currentBook, idx) {             
    // Cache the book, so that we can reset it later.
    var cachedBook = angular.copy(currentBook);
    var $outerScope = $scope;

    var modalInstance = $modal.open({
        // ...
        controller: [
            '$scope', '$modalInstance', function($scope, $modalInstance){
                $scope.editBook = currentBook;
                $scope.saveModal = function (book) {
                    // ...
                };
                $scope.cancelModal = function () {
                    //  Restore the previous state
                    $outerScope.books[idx] = cachedBook;

                    // ...
                };
            }]
    });
};

如果您希望自己的用户比实际保存编辑更频繁地点击Cancel,那么可能会考虑撤消操作并传入图书的副本而不是原件,只修改原件{ {1}}被调用。