我试图实施一种"回滚"特征。这就是我所拥有的:
从一个非常简单的对象开始:
var allMetals = [
{name: "Gold", rating: 9},
{name: "Silver", rating: 8},
{name: "Copper", rating: 7}];
他们可以编辑。我有一个处理编辑的指令。显示的列表如下:
<ul>
<li ng-repeat="m in allMetals">
{{m.name}}
<span>{{m.rating}}</span>
<a href="" ng-click="edit(m.name)"</a>
</li>
</ul>
转发器标记:
<div edit-metal="" metal="currentMetal" ng-show="editing"></div>
在编辑功能中,我只是设置currentMetal
设置标志的值,以便编辑指令变为可见。
function edit(name) {
$scope.currentMetal = helper.getMetalByName(name);
$scope.editing = true;
}
现在,在指令中,我有一个简单的文本框,它绑定到模型,当用户编辑时,我可以看到父范围var正在更新,一切都很花哨。 但有时,在编辑之后,我可能会改变主意并决定取消更改。所以我有一个取消功能就是这样做的。
// in the directive link()
var uneditedMetal = _.clone($scope.metal);
$scope.cancel = function(){
$scope.metal = uneditedMetal;
}
$scope.save = () {
//do nothing as parent handles save with a different user button
}
现在,为了实现这一点,我必须在用户每次点击“编辑”时更新指令的currentMetal
值,以便我可以在之前对其进行备份它的编辑;如果点击取消按钮。我尝试使用$scope.$watch('metal', function(){ /*clone here*/ })
进行此操作,但似乎触发了太多次,所以现在我在父{q} edit()
函数上广播并使用$scope.$on()
复制值的备份。
我不确定这是实现这一目标的最佳方式,如果您有任何建议请告诉我。
我的问题是,当调用cancel()
时,我知道正在设置的值是正确的值,它会更改指令中的值,但它不会传播到父作用域!
即使奇怪的是,如果我只是$scope.metal = uneditedMetal
而不是使用$scope.metal.name = "Mercury"
进行复制,那么这种变化就会被传播,但是对象分配和其他_.clone()
都不起作用。我不太清楚失去的变化在哪里。有任何想法吗?
这是一个复制我的问题的plnkr:http://plnkr.co/edit/VKLr8gMVLyYkNvJJOGKa?p=preview
任何见解都将不胜感激,谢谢。
重现问题的步骤:
我希望在点击取消时还原父更改,但它不会发生。
答案 0 :(得分:0)
我编写了内联编辑指令,它执行与您正在执行的操作相同的操作,编辑和取消编辑功能。 您可以将此指令用作:
<inline-edit
ng-model="yourmodel"
input-type="'text'"
label="your label'"
label-width="3"
input-width="9"
isdisabled="true">
</inline-edit>
angular.module('common.inlineEdit', [])
.directive('inlineEdit', ['$compile', '$timeout', function ($compile, $timeout ) {
return {
require: "ngModel",
restrict: 'E',
replace: true,
scope: {
updateFn: '&',
isdisabled: '=',
inputType: '=',
label: '=',
labelWidth: '=',
inputWidth: '='
},
templateUrl: "directives/inlineEdit/inlineEdit.tpl.html",
link: function(scope, elm, attrs, ngModel) {
scope.model = {};
var cancelEditTimer;
ngModel.$render = function() {
scope.model.value = ngModel.$viewValue;
};
scope.cancelEdit = function () {
cancelEditTimer = $timeout(function(){
scope.model.value = ngModel.$viewValue;
scope.editing = false;
},300);
};
scope.saveEdit = function () {
scope.editing = false;
scope.updateFn({value: scope.model.value});
};
scope.edit = function () {
scope.editing=true;
$timeout(function(){
scope.input = (elm[0].querySelector('input[type="text"]'));
scope.input.focus();
},100);
};
scope.select = function () {
$timeout(function(){
scope.editing=true;
$timeout.cancel(cancelEditTimer);
},10);
};
}
};
}]);
指令的模板文件是:
<div ng-mouseover="showEdit = true" ng-mouseleave="showEdit = false" class="row inline-edit">
<div class="col-sm-{{labelWidth}}">
<b>{{label}} </b>
</div>
<div class="col-sm-{{inputWidth}}">
<span ng-show="!editing">{{model.value}} </span>
<a href="javascript:void(0);" class="fa fa-pencil-square-o edit" ng-show="!isdisabled && showEdit && !editing" ng-click="edit()"></a>
<div class="row">
<div class="col-sm-8" ng-if="editing && inputType=='text'">
<input type="text" ng-model="model.value" class="form-control input-sm" ng-blur="cancelEdit()">
</div>
<div class="col-sm-4 action-buttons">
<a class="fa fa-check save" href="javascript:void(0);" ng-click="saveEdit()" ng-show="editing"></a>
<a class="fa fa-times cancel" href="javascript:void(0);" ng-click="cancelEdit()" ng-show="editing"></a>
</div>
</div>
</div>
</div>