如何在Angular中实现可取消的可编辑字段?

时间:2014-10-08 20:28:50

标签: javascript angularjs

在我的模型中,我有一个字段,我需要几个控件来绑定。其中一个控件是文本框。文本框不应该直接编辑该字段,而应该允许用户键入然后提交更改或取消。如果发生任何其他操作,则应覆盖文本字段中的任何更改。一个限制是,有其他UI组件可以更改值,并且无权访问本地范围。

我使用指令实现了所需的行为:http://jsfiddle.net/fLxjjmb7/3/

它按预期工作,但我觉得必须有更好的方法来做到这一点。有什么想法吗?

<div ng-app="app" ng-controller="controller">
    <div>{{foo}}</div>
    <button ng-click="increment()">increment</button>
    <button ng-click="decrement()">decrement</button>
    <br />
    <div shadow="foo">
        <input type="text" ng-model="foo" />
        <button ng-click="commit()">update</button>
        <button ng-click="cancel()">cancel</button>
    </div>
</div>
var app = angular.module('app', []);

var controller = app.controller('controller', function ($scope) {
    $scope.foo = 1;
    $scope.increment = function () { ++$scope.foo; };
    $scope.decrement = function () { --$scope.foo; };
});

var directive = app.directive('shadow', function() {
  return {
    scope: true,
    link: function(scope, el, att) {
        scope.$parent.$watch(att.shadow, function (newValue) {
            scope[att.shadow] = newValue;
        });

      scope.commit = function() {
        scope.$parent[att.shadow] = angular.copy(scope[att.shadow]);
      };

      scope.cancel = function() {
          scope[att.shadow] = angular.copy(scope.$parent[att.shadow]);
      };
    }
  };
});

1 个答案:

答案 0 :(得分:0)

认为你有点复杂了这一点:)

查看:

<div ng-controller="ShadowController">
    <h1>{{foo}}</h1>

    <div>
        <button ng-click="increment()">increment</button>
        <button ng-click="decrement()">decrement</button>
    </div>

    <div>
        <input type="text" ng-model="tempFoo" />
        <button ng-click="commit()">update</button>
        <button ng-click="cancel()">cancel</button>
    </div>
</div>

控制器:

.controller('ShadowController', function ($scope) {
    $scope.foo = 1;

    $scope.increment = function () {
        ++$scope.foo;
        $scope.cancel();
    };

    $scope.decrement = function () {
        --$scope.foo;
        $scope.cancel();
    };

    $scope.commit = function () {
        $scope.foo = parseFloat($scope.tempFoo);
    };

    $scope.cancel = function () {
        $scope.tempFoo = $scope.foo;
    };

    $scope.cancel();
});

更奇妙的方法是跟踪临时值的变化,只有在原始和临时之间存在差异时才启用提交/取消按钮。

查看:

<div ng-controller="ShadowControllerAdv">
    <h1>{{data.original}}</h1>

    <div>
        <button ng-click="increment()">increment</button>
        <button ng-click="decrement()">decrement</button>
    </div>

    <div>
        <input type="text" ng-model="data.edit" />
        <button ng-click="commit()" ng-disabled="!state.hasChanged">update</button>
        <button ng-click="reset()" ng-disabled="!state.hasChanged">cancel</button>
    </div>
</div>

控制器:

.controller('ShadowControllerAdv', function ($scope) {
    var _dataWatcher;

    $scope.data = {
        original: 1
    };

    $scope.state = {
        hasChanged: false
    };

    function _startWatcher() {
        _dataWatcher = $scope.$watch('data.edit', function (newValue, oldValue) {
            if (newValue !== oldValue) {
                $scope.state.hasChanged = true;
            } else {
                $scope.state.hasChanged = false;
            }
        }, true);
    }

    function _stopWatcher() {
        if (!_dataWatcher) {
            return;
        }
        _dataWatcher();
    }

    $scope.reset = function () {
        _stopWatcher();
        $scope.data.edit = $scope.data.original;
        $scope.state.hasChanged = false;
        _startWatcher();
    }

    $scope.commit = function () {
        _stopWatcher();
        $scope.data.original = parseFloat($scope.data.edit);
        $scope.reset();
    }

    $scope.increment = function () {
        $scope.data.original = $scope.data.original + 1;
        $scope.reset();
    };

    $scope.decrement = function () {
        $scope.data.original = $scope.data.original - 1;
        $scope.reset();
    };

    $scope.reset();
});