注意:这与显示AngularJS的模式对话框无关,该主题有很多问题和答案!
此问题是关于如何在页面上的模式对话框中对“确定”和“取消”做出反应。假设您有一个仅包含一个变量的范围:
$scope.description = "Oh, how I love porcupines..."
如果我在页面上为您提供了一个模式对话框,并在该对话框中使用ng-model =“ description”,则您所做的所有更改实际上都是在您键入内容时实时对说明本身进行的。不好,因为那您如何取消该对话框?
有一个问题说明我将在下面解释。可接受的答案是我想出的相同“解决方案”:AngularJS:数据绑定模式- 仅在单击“保存”时保存更改,或者在单击“取消”时忘记更改
如果单击按钮以调出模态,我将看到如何执行该操作,该操作返回到后面的函数,该函数为模态创建了相关数据的临时副本,然后弹出了模态。然后,“确定”(或“保存”或任何其他内容)可以将临时值复制到实际模型值。
main.js(节选):
$scope.descriptionUncommitted = $scope.description; $scope.commitChanges = function () { $scope.description = $scope.descriptionUncommitted; }
main.html(节选):
<input type="text" ng-model="descriptionUncommitted"/> <button ng-click="commitChanges()">Save</button>
问题在于 它不是声明性的 !实际上,它与其他任何地方都不像AngularJS。好像我们需要一个ng-model-uncommitted =“ description”一样,他们可以在其中进行所需的所有更改,但是只有在我们用另一个声明触发时,它们才会提交。某个插件中是否有这样的东西,或者AngularJS本身在添加它?
编辑:看来,一个不同的方法的例子可能是有序的。
main.js:
$scope.filename = "panorama.jpg"; $scope.description = "A panorama of the mountains."; $scope.persist = function () { // Some function to hit a back end service. };
main.html:
<form> <input type="text" ng-model-uncommitted="filename"/> <input type="text" ng-model-uncommitted="description"/> <button ng-commit ng-click="persist()">Save</button> <button ng-discard>Cancel</button> </form>
我在上面贴了一个表单标签,因为我不知道如何对项目进行分组,因此很明显,这都是同一笔“交易”的一部分(因为缺少更好的词)。但是需要某种方式可以使它们全部自动发生,并将模型变量的克隆副本用于初始值,用于输入并自动更新,验证等,然后最终丢弃或复制到与该值相同的值。如果用户决定提交,则最初用于创建它们。
这样的事情难道不是比控制器中的代码更容易在大型网站中针对20个模式进行一遍又一遍的工作吗?还是我疯了?
基本上,如果不是声明性的内容,则用角度表示,您就可以 编写指令 。
.directive('shadow', function() { return { scope: { target: '=shadow' }, link: function(scope, el, att) { scope[att.shadow] = angular.copy(scope.target); scope.commit = function() { scope.target = scope[att.shadow]; }; } };
然后:
<div shadow="data"> <input ng-model="data"> <button ng-click="commit()">save</button> </div>
因此data,shadow指令内部将是原始指令的 副本data。单击该按钮后,它将被复制回原始文件。
data
shadow
这是工作示例:jsbin
我没有在此示例之外对其进行测试,因此它可能在其他情况下不起作用,但是我认为它给出了可能的想法。
编辑:
另一个示例,其中包含一个对象而不是一个字符串,并且具有多个字段形式(angular.copy此处需要一个附加字段):jsbin
angular.copy
Edit2,有角版本1.2.x
根据此更改,input内部指令不再访问隔离的作用域。一种替代方法是创建一个非隔离的子作用域(scope:true),以保存数据副本并访问父作用域以进行保存。
input
scope:true
因此,对于较新的angular版本,此方法与之前进行修改的方法相同:
.directive('shadow', function() { return { scope: true, link: function(scope, el, att) { scope[att.shadow] = angular.copy(scope[att.shadow]); scope.commit = function() { scope.$parent[att.shadow] = angular.copy(scope[att.shadow]); }; } }; });
示例:jsbin
请注意,使用的问题$parent是,如果中间最终有另一个作用域,它可能会中断。
$parent