Joh*_*sch 64 javascript angularjs
注意:这不是关于使用AngularJS显示模态对话框,该主题有很多问题和答案!
这个问题是关于如何在页面上的模式对话框中对OK和Cancel做出反应.假设你有一个只有一个变量的范围:
$scope.description = "Oh, how I love porcupines..."
Run Code Online (Sandbox Code Playgroud)
如果我在页面上为您提供模式对话框并在该对话框中使用ng-model ="description",则您所做的所有更改实际上都是在您键入时实时对描述本身进行的.这很糟糕,因为那你怎么取消那个对话?
这个问题说要做我在下面解释的内容.它接受的答案与我提出的相同"解决方案":AngularJS:数据绑定模式 - 仅在单击"保存"时保存更改,或者如果单击"取消"则忘记更改
我可以看到如何做到这一点,如果单击按钮调出模态返回到后面的函数,并创建模态的相关数据的临时副本,然后弹出模态.然后"确定"(或"保存"或其他)可以将临时值复制到实际模型值.
main.js(摘录):
$scope.descriptionUncommitted = $scope.description;
$scope.commitChanges = function () {
$scope.description = $scope.descriptionUncommitted;
}
Run Code Online (Sandbox Code Playgroud)
main.html(摘录):
<input type="text" ng-model="descriptionUncommitted"/>
<button ng-click="commitChanges()">Save</button>
Run Code Online (Sandbox Code Playgroud)
问题在于它不是声明性的!事实上,它在任何其他地方都不像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. };
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
我在它周围粘贴了一个表单标签,因为我不知道你将如何对项目进行分组,因此很明显它是同一个"事务"的所有部分(缺少一个更好的单词).但是需要某种方式,这可以全部自动发生,模型变量的克隆副本用于初始值,用于输入和自动更新,验证等,然后最终丢弃或复制到相同的值,如果用户决定提交,则最初用于创建它们.
这样的事情是不是比控制器中的代码更容易在一个大网站上反复做20个模态的工作?还是我疯了?
gar*_*rst 23
基本上,如果某些东西不是声明性的,那么你就是一个指令.
.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];
};
}
};
Run Code Online (Sandbox Code Playgroud)
然后:
<div shadow="data">
<input ng-model="data">
<button ng-click="commit()">save</button>
</div>
Run Code Online (Sandbox Code Playgroud)
因此指令data内部shadow将是原始的副本data.单击按钮时,它将被复制回原始文件.
以下是工作示例:jsbin
我没有在这个例子之外测试它,所以它可能在其他情况下不起作用,但我认为它给出了可能性的概念.
编辑:
另一个使用对象而不是字符串的示例,以及表单中的多个字段(angular.copy此处需要额外的字段):jsbin
Edit2,角度版本1.2.x.
根据此更改,input指令内部不再访问隔离范围.另一种方法是创建一个非隔离的子范围(scope:true),以保存数据的副本并访问父范围以进行保存.
因此,对于更高版本的角度,这与之前稍作修改的方法相同:
.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]);
};
}
};
});
Run Code Online (Sandbox Code Playgroud)
示例:jsbin
请注意,使用的问题$parent是,如果最终中间有另一个范围,它可能会中断.
Sil*_*fer 21
从Angular 1.3开始,有一个ngModelOptions指令允许本机地执行相同的行为.
<form name="userForm">
<input type="text" ng-model="user.name" ng-model-options="{ updateOn: 'submit' }" name="userName">
<button type="submit">save</button>
<button type="button" ng-click="userForm.userName.$rollbackViewValue();">cancel</button>
</form>
Run Code Online (Sandbox Code Playgroud)
JSFiddle:http://jsfiddle.net/8btk5/104/
vit*_*ets 11
面对同样的问题,并通过这个线程,我想出的lazy-model指令完全相同,ng-model但只在提交表单时保存更改.
用法:
<input type="text" lazy-model="user.name">
Run Code Online (Sandbox Code Playgroud)
请注意将其包装成<form>标签,否则懒惰模型将不知道何时将更改推送到原始模型.
完整的工作演示:http://jsfiddle.net/8btk5/3/
lazyModel指令代码:(
更好地使用github上的实际版本)
app.directive('lazyModel', function($parse, $compile) {
return {
restrict: 'A',
require: '^form',
scope: true,
compile: function compile(elem, attr) {
// getter and setter for original model
var ngModelGet = $parse(attr.lazyModel);
var ngModelSet = ngModelGet.assign;
// set ng-model to buffer in isolate scope
elem.attr('ng-model', 'buffer');
// remove lazy-model attribute to exclude recursion
elem.removeAttr("lazy-model");
return function postLink(scope, elem, attr) {
// initialize buffer value as copy of original model
scope.buffer = ngModelGet(scope.$parent);
// compile element with ng-model directive poining to buffer value
$compile(elem)(scope);
// bind form submit to write back final value from buffer
var form = elem.parent();
while(form[0].tagName !== 'FORM') {
form = form.parent();
}
form.bind('submit', function() {
scope.$apply(function() {
ngModelSet(scope.$parent, scope.buffer);
});
});
form.bind('reset', function(e) {
e.preventDefault();
scope.$apply(function() {
scope.buffer = ngModelGet(scope.$parent);
});
});
};
}
};
});
Run Code Online (Sandbox Code Playgroud)
你好像在想这个.没有插件,因为这个过程非常简单.如果您需要模型的原始副本,请创建一个并将其保留在控制器中.如果用户取消,请将模型重置为您的副本,并使用FormController.$ setPristine()方法再次使表单保持原样.
//Controller:
myService.findOne({$route.current.params['id']}, function(results) {
$scope.myModel = results;
var backup = results;
}
//cancel
$scope.cancel = function() {
$scope.myModel = backup;
$scope.myForm.$setPristine();
}
Run Code Online (Sandbox Code Playgroud)
然后在你看来:
<form name="myForm">
Run Code Online (Sandbox Code Playgroud)
您需要命名表单以创建$ scope.myForm控制器.
| 归档时间: |
|
| 查看次数: |
36592 次 |
| 最近记录: |