序言:看起来这个问题之前已经被问过并得到了回答,但我似乎无法让它工作,所以如果我的问题归结为"你可以调试我的代码吗?" ,我道歉。
我想写下面的代码:
<radio-set ng-model="obj.prop" name="obj_prop">
<radio-set-button ng-value="'public'">Public</radio-set-button>
<radio-set-button ng-value="'protected'">Protected</radio-set-button>
<radio-set-button ng-value="'private'">Private</radio-set-button>
</radio-set>
这会呈现一堆单选按钮和标签,需要填充传递给<radio-set>
的ngModel的内容。我遗漏了与范围相关的内容。
.directive("radioSet", function () {
return {
restrict: 'E',
replace: true,
scope: {
ngModel: '=?',
ngChange: '&',
name: '@'
},
transclude: true,
template: '<div class="radio-set" ng-transclude></div>',
controller: function () {}
};
})
.directive("radioSetButton", function () {
return {
restrict: 'E',
replace: true,
require: ['^radioSet', '?ngModel'],
scope: {
ngModel: '=?', // provided by ^radioSet?
ngValue: '=?',
ngChange: '&', // provided by ^radioSet?
name: '@' // provided by ^radioSet?
},
transclude: true,
link: function (scope, element, attr) {
element.children().eq(0).attr("name", scope.name); // scope.name is null
},
template: '<label class="radio-set-button">' +
'<input type="radio" name="name" ng-model="ngModel" ng-value="ngValue" ng-change="ngChange()">' +
'<div class="radio-content" ng-transclude></div>' +
'</label>'
};
})
父指令和子指令都需要自己的范围定义,但我不清楚如何从radioSet
内访问radioSetButton
的范围。
感谢您的帮助。
答案 0 :(得分:2)
我想我必须告诉你,你在指令中使用的翻译并不像你期望的那样有效,因为简而言之:被转换的指令并没有继承你期望的范围,实际上它继承了外部控制器的范围,但是在这个主题上有很多答案:
Access Parent Scope in Transcluded Directive
要访问父母指令,基本上有两种方法:
1。)需要父母指令的控制器并创建一些API来做父母的事情
2.。)使用link函数的第五个参数来访问transclude函数,在这里你可以改变注入的范围,你可以将它设置为parent指令范围
由于第一个解决方案更直观,我会选择这个:
在radioSet
指令中,我在Controller中设置了对象的双向数据绑定,并创建了一个getter和setter方法来与值进行交互。
在&#34; child&#34;的指令中,我需要父指令的控制器,我将其作为链接函数中的第四个参数传递。我在元素上设置了一个点击处理程序来获取点击,在这里我用我的值调用父设置器方法。为了可视化当前所选对象,我添加了一个ng-class
指令,它有条件地添加了活动类。
注意:这样您也可以使用ngModel
指令。它有一个与模型交互的API。
第二个解决方案使用transclude函数,您可以使用该函数传入范围。由于我现在没有时间,因为它增加了更多的复杂性,我建议使用第一个解决方案。
对于您的示例,转换可能不是正确的选择,请使用一个指令并将选项添加到模板或将它们传递给指令。因为我不知道你的意图是什么,我提供了这个解决方案。 (我不知道这个名称属性的用途是什么?)
小提琴:http://jsfiddle.net/q3nUk/
样板:
var app = angular.module('myApp', []);
app.controller('MainController', function($scope) {
$scope.object = {
'property' : 'public'
};
});
指令:
app.directive('radioSet', function() {
return {
scope : {
radioValue : '='
},
restrict : 'E',
transclude : true,
replace : true,
template : '<div class="radioSet" ng-transclude></div>',
controller : function($scope) {
this.getRadioValue = function() {
return $scope.radioValue;
}
this.setRadioValue = function(val) {
$scope.$apply(function() {
$scope.radioValue = val
});
}
}
};
});
app.directive('radioSetButton', function() {
return {
restrict : 'E',
transclude : true,
replace : true,
scope : true,
template : '<div class="radioSetButton" ng-class="{active:isActive()}" ng-transclude></div>',
require : '^radioSet',
link : function(scope, elem, attrs, radioSetController, transclude) {
scope.isActive = function() {
return attrs.buttonValue === radioSetController.getRadioValue();
};
elem.on('click', function() {
radioSetController.setRadioValue(attrs.buttonValue);
});
}
};
});
HTML:
<html>
<body ng-app="myApp">
<div ng-controller="MainController">
<p>{{ object.property }}</p>
<radio-set radio-value="object.property">
<radio-set-button button-value="public">Public</radio-set-button>
<radio-set-button button-value="private">Private</radio-set-button>
<radio-set-button button-value="protected">Protected</radio-set-button>
</radio-set>
</div>
</body>
</html>
CSS:
.radioSetButton {
display : block;
padding : 10px;
border : 1px solid black;
float : left;
}
.radioSetButton:hover {
cursor : pointer;
}
.radioSetButton.active {
background-color : grey;
}