如何在 ng-repeat 中使用 ng-switch 来编辑 JSON API 数据
Howto use ng-switch inside ng-repeat for editing JSON API data
我知道这是一个反复出现的问题,但遗憾的是我找不到合适的答案来解决我的问题。
基本上我从 JSON API 端点获取数据,这些端点使用 ng-repeat
显示在 table 中。我现在想 ng-switch
视图输入字段以修改数据(并稍后将其发送回服务器)。
Atm,我的解决方案取决于我不太喜欢的数据中的 属性。我确信有比在检索数据后注入此 属性 更聪明的方法 - 有什么建议吗?
HTML:
<tbody>
<tr ng-repeat="item in data" ng-switch on="item.edit" >
<td ng-switch-default ng-bind="item.color"></td>
<td ng-switch-when='true'>
<input type="text" ng-model="item.color" />
</td>
<td ng-switch-default><button ng-click="switch(item)">edit</button></td>
<td ng-switch-when='true'><button ng-click="send(item)">send</button></td>
</tr>
</tbody>
JS:
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
$scope.switch = function (item) {
if (item.edit) {
item.edit = false;
} else {
item.edit = true;
}
};
$scope.send = function (item) {
if (item.edit) {
// data is sent...
item.edit = false;
} else {
item.edit = true;
}
};
$scope.data = [
{color: 'blue', edit: false},
{color: 'green', edit: false},
{color: 'orange', edit: false}];
});
提前致谢!
我正在使用 ng-show,但希望这展示了一种更好的方法:
http://plnkr.co/edit/63Io7k1mJcfppxBQUVef?p=preview
我正在使用 ng-show
,我只是在需要时将 "edit" 隐式附加到对象,因为您不需要立即将其设置为 true。缺少 属性 将意味着它 returns 错误。
标记:
<tbody>
<tr ng-repeat="item in data">
<td ng-show="!item.edit" ng-bind="item.color"></td>
<td ng-show='item.edit'>
<input type="text" ng-model="item.color" />
</td>
<td><button ng-click="edit(item)">{{item.edit ? "Send" : "Edit"}}</button></td>
</tr>
</tbody>
对于这种情况,我总是将视图状态封装在一个指令中。这里的意思是为每一行创建一个指令,并在该指令中移动item.edit
标志。
下面是一个非常天真的实现:
HTML:
<tbody>
<tr ng-repeat="item in data" inplace-edit="item" send-callback="send(item)"></tr>
</tbody>
JS:
app.directive('inplaceEdit', function() {
return {
restrict: 'A',
template:
'<td ng-if="!inEditMode" ng-bind="item.color"></td>' +
'<td ng-if="inEditMode">' +
'<input type="text" ng-model="item.color" />' +
'</td>' +
'<td ng-if="!inEditMode"><button ng-click="toEditMode()">edit</button></td>' +
'<td ng-if="inEditMode"><button ng-click="send()">send</button></td>',
scope: {
item: '=inplaceEdit',
sendCallback: '&'
},
link: function(scope) {
scope.inEditMode = false;
scope.toEditMode = function() {
scope.inEditMode = true;
};
scope.send = function() {
scope.sendCallback({item: scope.item});
scope.inEditMode = false;
};
}
};
});
查看分叉的 plunk:http://plnkr.co/edit/BS6a866aiy3BA9MX0Flx?p=preview
我要添加什么来使它现代化:
controllerAs
、bindToController
- rollback/undo 更改的一些代码(即编辑模式下的 "cancel" 按钮)
- 使用 Angular 1.5.x 和单向绑定:
item: '>inplaceEdit'
或将 inplace-edit
指令与 ng-model 集成
如果您不想将标志放在数据对象上,则需要使用单独的对象来存储它们。使用 WeakMaps 您可以轻松地将数据对象或元素本身与标志对象相关联。如果您的目标是较旧的浏览器,您将需要找到一种类似的方式将数据对象/或元素关联到标志对象
JS
let map = new WeakMap();
$scope.editing = function(item){
return map.get(item).edit;
}
$scope.switch = function (item) {
let flags = map.get(item);
if (flags.edit) {
flags.edit = false;
} else {
flags.edit = true;
}
};
//Note you could combine switch and send into a single toggle function
$scope.send = function (item) {
let flags = map.get(item);
if (flags.edit) {
flags.edit = false;
} else {
flags.edit = true;
}
};
$scope.data = [
{color: 'blue'},
{color: 'green'},
{color: 'orange'}
];
//Create an empty flags object for each data item
for(let item of $scope.data){
map.set(item,{});
}
HTML
<tr ng-repeat="item in data" ng-switch on="editing(item)" >
<td ng-switch-default ng-bind="item.color"></td>
<td ng-switch-when='true'>
<input type="text" ng-model="item.color" />
</td>
<td ng-switch-default><button ng-click="switch(item)">edit</button></td>
<td ng-switch-when='true'><button ng-click="send(item)">send</button></td>
</tr>
演示
// Code goes here
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
var map = new WeakMap();
//Using fat arrow less code to write
$scope.editing = item=>map.get(item).edit;
//Since "switch" and "send" had similar
//toggling code just combined them
//Also no need to use if statement, just use the NOT operator
//to toggle the edit flag
$scope.toggle = item=>{
let flags = map.get(item);
flags.edit = !flags.edit;
};
$scope.switch = item=>{
$scope.toggle(item);
//Do some switching?
//if not doing anything else just
//call toggle in the ng-click
};
$scope.send = item=>{
$scope.toggle(item);
//Do some sending
};
$scope.data = [
{color: 'blue'},
{color: 'green'},
{color: 'orange'}];
for(let item of $scope.data){
map.set(item,{});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<table>
<thead>
<tr>
<th width="180">Column</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data" ng-switch on="editing(item)" >
<td ng-switch-default ng-bind="item.color"></td>
<td ng-switch-when='true'>
<input type="text" ng-model="item.color" />
</td>
<td ng-switch-default><button ng-click="switch(item)">edit</button></td>
<td ng-switch-when='true'><button ng-click="send(item)">send</button></td>
</tr>
</tbody>
</table><br>
"$scope.data" should never change after hitting edit/send since the flag is no longer on the data item object:
<code><pre>{{data}}</pre></code>
</div>
我知道这是一个反复出现的问题,但遗憾的是我找不到合适的答案来解决我的问题。
基本上我从 JSON API 端点获取数据,这些端点使用 ng-repeat
显示在 table 中。我现在想 ng-switch
视图输入字段以修改数据(并稍后将其发送回服务器)。
Atm,我的解决方案取决于我不太喜欢的数据中的 属性。我确信有比在检索数据后注入此 属性 更聪明的方法 - 有什么建议吗?
HTML:
<tbody>
<tr ng-repeat="item in data" ng-switch on="item.edit" >
<td ng-switch-default ng-bind="item.color"></td>
<td ng-switch-when='true'>
<input type="text" ng-model="item.color" />
</td>
<td ng-switch-default><button ng-click="switch(item)">edit</button></td>
<td ng-switch-when='true'><button ng-click="send(item)">send</button></td>
</tr>
</tbody>
JS:
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
$scope.switch = function (item) {
if (item.edit) {
item.edit = false;
} else {
item.edit = true;
}
};
$scope.send = function (item) {
if (item.edit) {
// data is sent...
item.edit = false;
} else {
item.edit = true;
}
};
$scope.data = [
{color: 'blue', edit: false},
{color: 'green', edit: false},
{color: 'orange', edit: false}];
});
提前致谢!
我正在使用 ng-show,但希望这展示了一种更好的方法:
http://plnkr.co/edit/63Io7k1mJcfppxBQUVef?p=preview
我正在使用 ng-show
,我只是在需要时将 "edit" 隐式附加到对象,因为您不需要立即将其设置为 true。缺少 属性 将意味着它 returns 错误。
标记:
<tbody>
<tr ng-repeat="item in data">
<td ng-show="!item.edit" ng-bind="item.color"></td>
<td ng-show='item.edit'>
<input type="text" ng-model="item.color" />
</td>
<td><button ng-click="edit(item)">{{item.edit ? "Send" : "Edit"}}</button></td>
</tr>
</tbody>
对于这种情况,我总是将视图状态封装在一个指令中。这里的意思是为每一行创建一个指令,并在该指令中移动item.edit
标志。
下面是一个非常天真的实现:
HTML:
<tbody>
<tr ng-repeat="item in data" inplace-edit="item" send-callback="send(item)"></tr>
</tbody>
JS:
app.directive('inplaceEdit', function() {
return {
restrict: 'A',
template:
'<td ng-if="!inEditMode" ng-bind="item.color"></td>' +
'<td ng-if="inEditMode">' +
'<input type="text" ng-model="item.color" />' +
'</td>' +
'<td ng-if="!inEditMode"><button ng-click="toEditMode()">edit</button></td>' +
'<td ng-if="inEditMode"><button ng-click="send()">send</button></td>',
scope: {
item: '=inplaceEdit',
sendCallback: '&'
},
link: function(scope) {
scope.inEditMode = false;
scope.toEditMode = function() {
scope.inEditMode = true;
};
scope.send = function() {
scope.sendCallback({item: scope.item});
scope.inEditMode = false;
};
}
};
});
查看分叉的 plunk:http://plnkr.co/edit/BS6a866aiy3BA9MX0Flx?p=preview
我要添加什么来使它现代化:
controllerAs
、bindToController
- rollback/undo 更改的一些代码(即编辑模式下的 "cancel" 按钮)
- 使用 Angular 1.5.x 和单向绑定:
item: '>inplaceEdit'
或将inplace-edit
指令与 ng-model 集成
如果您不想将标志放在数据对象上,则需要使用单独的对象来存储它们。使用 WeakMaps 您可以轻松地将数据对象或元素本身与标志对象相关联。如果您的目标是较旧的浏览器,您将需要找到一种类似的方式将数据对象/或元素关联到标志对象
JS
let map = new WeakMap();
$scope.editing = function(item){
return map.get(item).edit;
}
$scope.switch = function (item) {
let flags = map.get(item);
if (flags.edit) {
flags.edit = false;
} else {
flags.edit = true;
}
};
//Note you could combine switch and send into a single toggle function
$scope.send = function (item) {
let flags = map.get(item);
if (flags.edit) {
flags.edit = false;
} else {
flags.edit = true;
}
};
$scope.data = [
{color: 'blue'},
{color: 'green'},
{color: 'orange'}
];
//Create an empty flags object for each data item
for(let item of $scope.data){
map.set(item,{});
}
HTML
<tr ng-repeat="item in data" ng-switch on="editing(item)" >
<td ng-switch-default ng-bind="item.color"></td>
<td ng-switch-when='true'>
<input type="text" ng-model="item.color" />
</td>
<td ng-switch-default><button ng-click="switch(item)">edit</button></td>
<td ng-switch-when='true'><button ng-click="send(item)">send</button></td>
</tr>
演示
// Code goes here
var app = angular.module('myApp', []);
app.controller('MyCtrl', function($scope) {
var map = new WeakMap();
//Using fat arrow less code to write
$scope.editing = item=>map.get(item).edit;
//Since "switch" and "send" had similar
//toggling code just combined them
//Also no need to use if statement, just use the NOT operator
//to toggle the edit flag
$scope.toggle = item=>{
let flags = map.get(item);
flags.edit = !flags.edit;
};
$scope.switch = item=>{
$scope.toggle(item);
//Do some switching?
//if not doing anything else just
//call toggle in the ng-click
};
$scope.send = item=>{
$scope.toggle(item);
//Do some sending
};
$scope.data = [
{color: 'blue'},
{color: 'green'},
{color: 'orange'}];
for(let item of $scope.data){
map.set(item,{});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<table>
<thead>
<tr>
<th width="180">Column</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data" ng-switch on="editing(item)" >
<td ng-switch-default ng-bind="item.color"></td>
<td ng-switch-when='true'>
<input type="text" ng-model="item.color" />
</td>
<td ng-switch-default><button ng-click="switch(item)">edit</button></td>
<td ng-switch-when='true'><button ng-click="send(item)">send</button></td>
</tr>
</tbody>
</table><br>
"$scope.data" should never change after hitting edit/send since the flag is no longer on the data item object:
<code><pre>{{data}}</pre></code>
</div>