【发布时间】:2015-03-19 11:16:28
【问题描述】:
Angularjs:ng-repeat 中的复杂指令,如何绑定 ngModel 或 ngChecked in 指令并使其工作? 给定数组:
+----+-----------+----------+----------+-------+
| id | name | parentid | haschild | value |
+----+-----------+----------+----------+-------+
| 1 | parent | null | false | true |
| 2 | id1 child | 1 | true | true |
| 3 | id2 child | 2 | true | true |
| 4 | id3 child | 3 | false | true |
| 5 | id1 child | 1 | true | true |
| 6 | id5 child | 5 | false | true |
+----+-----------+----------+----------+-------+
$scope.permission = [
{"id":1,"name":"parent","value":true,"parentid":"","haschild":false},
{"id":2,"name":"id-1 child","value":true,"parentid":1,"haschild":true},
{"id":3,"name":"id-2 child","value":true,"parentid":2,"haschild":true},
{"id":4,"name":"id-3 child","value":true,"parentid":3,"haschild":false},
{"id":5,"name":"id-1 child","value":true,"parentid":1,"haschild":true},
{"id":6,"name":"id-5 child","value":true,"parentid":5,"haschild":false}
];
所以在html中
<div ng-repeat="x in permission" ng-if="x.parentid == undefined" has-child="{{x}}"></div>
和指令
myApp.directive('hasChild', function($compile) {
return function(scope, element, attrs) {
var j = JSON.parse(attrs.hasChild);
function generatePermissionDom(thisElement,thisParent)
{
angular.forEach(scope.permission,function(o,i){
if(thisParent.id==o.parentid)
{
var e = $('<div><input type="checkbox" ng-model="o.value"/>'+o.name+'</div>');
generatePermissionDom(e,o);
$(thisElement).append(e);
}
});
}
if(j.haschild)
angular.forEach(scope.permission,function(o,i){
if(o.parentid==j.id)
{
var e = $('<div><input type="checkbox" ng-model="o.value"/>'+o.name+'</div>');
if(o.haschild)
generatePermissionDom(e,o);
$(element).append(e);
}
});
var p = $(element);
$compile(element.contents())(scope);
}
});
那么如何在指令中绑定模型值呢? 这是笨蛋 http://plnkr.co/edit/QYqfEVaQF8WmUvB1aHB6?p=preview
附加信息:
haschild 表示父元素有子元素
例如:
1.人A拥有多家公司,所以人A有孩子
2.那么其中一家公司有多名员工,那么该公司有孩子。 所以在我的指令中,如果这个元素(假设这是元素 A)有子元素,则生成子元素并输入并绑定到 ngModel。
我的回答:这是我的想法和简单的实现方式 http://plnkr.co/edit/olKb5oBoxv0utlNcBQPg?p=preview
var app = angular.module('plunk', []);
app.directive('generatePermissions', function($compile) {
return {
restrict : "E",
scope : true,
require : 'ngModel',
link:function(scope,element,attrs,ngModel)
{
function generatePermissionDom(parent,parentElement)
{
angular.forEach(scope.list,function(o,i){
if(parent.id==o.parentid)
{
var e = angular.element('<div style="border:1px solid red"><input type="checkbox" ng-model="list['+i+'].value"/></div>');
if(o.haschild)
generatePermissionDom(o,e);
parentElement.append(e);
}
});
}
angular.forEach(scope.list,function(o,i){
if(o.parentid == null)
{
var e = angular.element('<div style="border:1px solid red"><input type="checkbox" ng-model="list['+i+'].value"/></div>');
if(o.haschild)
generatePermissionDom(o,e);
element.append(e);
}
});
var p = $(element);
$compile(p.contents())(scope);
}
}
});
app.controller('MainCtrl', function($scope) {
$scope.list = [{"id":1,"name":"parent","value":true,"parentid":null,"haschild":true},{"id":2,"name":"id-1 child","value":false,"parentid":1,"haschild":true},{"id":3,"name":"id-2 child","value":false,"parentid":2,"haschild":true},{"id":4,"name":"id-3 child","value":false,"parentid":3,"haschild":false},{"id":5,"name":"id-1 child","value":false,"parentid":1,"haschild":true},{"id":6,"name":"id-5 child","value":false,"parentid":5,"haschild":false}];
$scope.checkValue = function()
{
angular.forEach($scope.list,function(o,i){
console.log("id:"+o.id+" name:"+o.name+" value:"+o.value);
});
}
});
html
<body ng-controller="MainCtrl">
<generate-permissions ng-model="list"></generate-permissions>
<button ng-click="checkValue()">check</button>
</body>
不过,我认为 @NewDev 的答案 是正确答案!
【问题讨论】:
-
你能用文字解释一下你的
hasChild指令试图做什么吗? -
我还是不太明白。您似乎想根据对象的层次结构生成复选框的 DOM 树?我接近了吗?我不明白为什么你有
ng-repeat -
@NewDev 是的,你说得对。对于 ng-repeat,你可以忽略它,它可以在指令中设置。只是我只拿出来。
标签: javascript angularjs angularjs-directive angularjs-scope angularjs-ng-repeat