javascript Angularjs 动态添加带有子元素和模型的新 div
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20806927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angularjs Dynamically add new div with child elements and model
提问by skwidgets
I have a jsfiddle set up at http://jsfiddle.net/skwidgets/gnvVY/13/
我在http://jsfiddle.net/skwidgets/gnvVY/13/设置了一个 jsfiddle
Basically there is a div with a few form elements in it including two drop down menus a radio button group and a link to remove that row.
基本上有一个带有一些表单元素的 div,其中包括两个下拉菜单、一个单选按钮组和一个删除该行的链接。
<div ng-app="myapp">
<div id="w" ng-controller="survey">
<div class="qs">
<div class="">1</div>
<div class="">
<select data-role="none" name="w1.selected_location" data-ng-model="w.w1.selected_location" ng-options="location.value as location.label for location in locations">
<option value="">Choose a Location</option>
</select>
</div>
<div class="">
<select data-role="none" name="selected_stage" data-ng-model="w.w1.selected_stage" ng-options="stage.value as stage.label for stage in stages">
<option value="">Choose a Stage</option>
</select>
</div>
<div class="">
<input data-role="none" type="radio" name="wI4" value="true" data-ng-model="w.w1.wIn24">
</div>
<div class="">
<input data-role="none" type="radio" name="wI4" value="false" data-ng-model="w.w1.wIn24">
</div> <a href="#">Remove</a>
</div>
<div>
<button data-role="none">Add Row/button>{{w | json}}</div>
</div>
</div>
<script>
var locations = [{
label: 'Head',
value: 9,
}, {
label: 'Shoulders',
value: 5,
}
// ... more would go here
];
var stages = [{
label: 'I',
value: 0
}, {
label: 'II',
value: 1
}];
</script>
They are wrapped in a div with a class of "qs". All the selections are populated to a model called "w1" There is a button to add another row of these form elements and there parental container to the dom if the user wants to add another but it has to have a different model name that is similar to the first of (w1) but the number in the model name is incremented (w2, w3, and so forth) and so is the row number.
它们被包裹在一个带有“qs”类的 div 中。所有选择都填充到一个名为“w1”的模型中 如果用户想要添加另一个但它必须有一个不同的模型名称,则有一个按钮可以添加另一行这些表单元素和父容器到 dom到 (w1) 的第一个,但模型名称中的数字递增(w2、w3 等),行号也是如此。
I have tried to make a directive to handle the behavior but have not had any luck.
我试图制定一个指令来处理这种行为,但没有任何运气。
Any Ideas will be appreciated.
任何想法将不胜感激。
回答by Nikos Paraskevopoulos
The way to accomplish this in Angular (and MVVM frameworks generally) is to control the model. The model is naturally an array of objects, each object having the properies selected_location
, selected_stage
, wIn24
. So start by this (following your naming, it can be improved):
在 Angular(以及一般的 MVVM 框架)中实现这一点的方法是控制模型。模型自然是一个对象数组,每个对象都有属性selected_location
, selected_stage
, wIn24
。所以从这个开始(按照你的命名,它可以改进):
function Model() {
this.selected_location = null;
this.selected_stage = null;
this.wIn24 = null;
}
$scope.w = {
w: [ new Model() ]
};
Now place the repeated part in an ng-repeat
:
现在将重复的部分放在一个ng-repeat
:
<div ng-repeat="ww in w.w">
And adjust the ng-model
s accordingly, e.g.:
并相应地调整ng-model
s,例如:
<select data-role="none" data-ng-model="ww.selected_location"
ng-options="location.value as location.label for location in locations">
<option value="">Choose a Location</option>
</select>
Whenever a name is required and should be unique, use the {{ $index }}
, if no id is available:
每当需要名称并且应该是唯一的时{{ $index }}
,如果没有可用的 id,请使用 :
<input data-role="none" type="radio" name="wI4_{{$index}}" value="true"
data-ng-model="ww.wIn24" />
Finally put the add()
and remove()
functions in the scope:
最后把add()
和remove()
函数放在作用域中:
$scope.add = function() {
$scope.w.w.push(new Model());
};
$scope.remove = function(ww) {
var index = $scope.w.w.indexOf(ww);
if( index >= 0 ) $scope.w.w.splice(index,1);
};
And bind them to the template:
并将它们绑定到模板:
<a ng-click="remove(ww)">Remove</a>
<button data-role="none" ng-click="add()">Add Wound</button>
This fiddle has the complete solution: http://jsfiddle.net/x9NjJ/
这个小提琴有完整的解决方案:http: //jsfiddle.net/x9NjJ/
EDIT:The fiddle above vanished, including a full reconstructed source:
编辑:上面的小提琴消失了,包括一个完整的重建源:
HTML:
HTML:
<div ng-app="app" ng-controller="survey">
<div ng-repeat="ww in w.w">
<select data-role="none" data-ng-model="ww.selected_location"
ng-options="location.value as location.label for location in locations">
<option value="">Choose a Location</option>
</select>
<select data-role="none" data-ng-model="ww.selected_stage"
ng-options="stage.value as stage.label for stage in stages">
<option value="">Choose a Stage</option>
</select>
In 24: <input data-role="none" type="radio" name="wI4_{{$index}}" value="true" data-ng-model="ww.wIn24" />Yes
<input data-role="none" type="radio" name="wI4_{{$index}}" value="false" data-ng-model="ww.wIn24" />No
<a href="#" ng-click="remove(ww, $event)" style="display:inline-block; margin-left: 20px;">Remove</a>
</div>
<button data-role="none" ng-click="add()">Add Wound</button>
</div>
Javascript:
Javascript:
var app = angular.module('app', []);
function Model() {
this.selected_location = null;
this.selected_stage = null;
this.wIn24 = null;
}
app.controller('survey', function($scope) {
$scope.w = {
w: [ new Model() ]
};
$scope.add = function() {
$scope.w.w.push(new Model());
};
$scope.remove = function(ww, $event) {
$event.preventDefault();
var index = $scope.w.w.indexOf(ww);
if( index >= 0 ) $scope.w.w.splice(index,1);
};
$scope.locations = [
{
label: 'Head',
value: 9,
},
{
label: 'Shoulders',
value: 5,
}
// ... more would go here
];
$scope.stages = [
{
label: 'I',
value: 0
},
{
label: 'II',
value: 1
}
];
});
回答by gopesh
you can use this code for adding dynamic blocks
您可以使用此代码添加动态块
<div ng-app="" ng-controller="customersController">
<ul>
<li ng-repeat="x in names">
<div>{{ x.Country }}</div>
</li>
</ul>
<script>
function customersController($scope,$http) {
$http.get("http://www.w3schools.com/website/Customers_JSON.php")
.success(function(response) {$scope.names = response;});}
</script>