我在使用ng-model
和button
进行数据绑定时遇到了一个令人恼火的问题。
我的网站的操作原理:
- 我的HTML站点显示
projects
(从外部.json文件加载)的列表 - 每行都有一个名为
Edit
的按钮,它显示一个modal
,其中包含一些<input type="text"
,其中填充了有关项目的相关数据(如project.name
、project.date
等) - 输入的初始
value
等于对象数据(称为Name
的文本输入将包含project.name
等) - 只有单击
Save
按钮并确认操作(confirm(sometext)
正常),对象才会被修改。关闭模态、不点击按钮或按下确认框上的cancel
应防止数据更新 - 编辑输入(假设
project.name
是"Project2",我通过添加3个数字来修改它,得到"Project2137"),关闭模态并再次打开它,应该会在输入中产生"Project2)文本(因为对象没有修改,只有输入)
到目前为止,我理解单个文本输入应该看起来像这个
<input type="text" id="editName" class="form-control" ng-model = "project.name">
使用ng-model
意味着它们被绑定。这就是我所知道的。然而,编辑输入意味着一旦我输入一些数据,对象就会更新。我试着摆弄ng-model-options
,但没有找到任何可能的解决方案。
我试着用编程
<input type="text" id="editName" class="form-control" value = {{project.name}}>
....
<button type="button" class="btn pull-right btn-primary btn-md" ng-click="edit(project)" data-dismiss="modal" >Save</button>
和功能:
$rootScope.edit = function(project)
{
if(confirm("Are you sure to save changes?"))
{
project.name = angular.element(document.getElementById('editName')).val();
// ...and so on with other properties
这个解决方案有点接近我想要实现的(对象只在确认时更新),但我面临另一个问题:Input在开始时只从对象加载一次数据,而不是每次打开模态时都加载一次,这违反了规则#5
有什么方法可以使用ng-model
绑定或自定义函数来解决这个问题吗?或者也许还有其他更简单的方法?
--编辑--
在这里,我对使用按钮保存数据没有任何问题,一切都很好,单击保存会反映在projects
列表中。(直到我按下F5键)。问题是输入文本没有正确绑定到project
,这就是我想要解决的问题。
样本数据(伪代码)
project1.name="项目1"project2.name="Proj2">
我点击第1行上的编辑按钮
- 文本输入显示"Proj1"。一切都很好
- 我通过添加一些随机字符来更改输入,如"Proj1pezxde1">
- 文本输入现在为"Proj1pezxde1">
- 我不单击
Save
按钮 - 我关闭模态
- 项目摘要仍然显示"Proj1"。好的
- 我单击第一行的编辑按钮
10.即使我没有修改对象,文本输入也是"Proj1pezxde1">
文本输入应再次读取对象中的数据(每次打开此模式时),从而显示"Proj1">
这就是我想解决的问题。抱歉有点不准确。
您可以在模态控制器中创建项目对象的副本,并使用该对象与模态的输入元素绑定
$scope.copyProj = angular.copy($scope.project);
只有在单击"保存"时,才能将复制对象特性指定给项目。
根据我在阅读所提供的描述后的理解,您有一个项目列表,它被用作中继器,您希望将每个项目数据绑定到一个文本框和一个按钮。
您是否尝试过按照以下方式初始化Projects对象?
$scope.projects = [
{ 'name': 'proj1', 'id': '1' },
{ 'name': 'proj2', 'id': '2' }
];
然后你可以做下面这样的事情来显示你的数据
<div ng-repeat="project in projects">
<div>
<input type="text" class="form-control" ng-model = "project.name">
<button type="button" class="btn pull-right btn-primary btn-md" ng-click="edit(project)" data-dismiss="modal" >Save</button>
</div>
</div>
在我看来,最简单的方法是使用第二个对象,即项目的副本,并在确认后将更改应用于原始项目对象。
例如,控制器的一个简单"伪代码":
function MyCtrl($scope) {
$scope.projects = [...];
$scope.currentProject = null;
$scope.edit = function(project) {
$scope.currentProject = angular.copy(project); // This will create a copy so the changes in $scope.currentProject will not reflect.
// Open dialog with input bound to $scope.currentProject
if (confirm) {
// Assign all properties from currentProject to project
angular.extend(project, $scope.currentProject);
}
}
}
因此,正如我从您的问题中了解到的,只有在保存了项目数据的情况下,您才需要更新项目数据。要做到这一点,你可以维护一个实际对象的副本,只更新它,保存如下:
这里我们使用的是angular.copy(),它对源对象进行深度复制。
$scope.original = {name : "xyz"};
$scope.project = angular.copy(original);
//Call this when the user confirms to save , here we are replacing the
//original copy with the latest object that needs to be saved.
$scope.save = function () {
$scope.original = angular.copy($scope.project);
}
//Call this when closing the modal or clicking cancel or when losing
//focus, this will reset the changes to the original copy.
$scope.reset = function () {
$scope.project = angular.copy(original);
}