我正在尝试为复选框创建一个功能切换开关指令。我已经尝试了一些来自github的常见解决方案,但没有一个完成以下所有操作:
ng-true-value
但是,如果我创建一个使用transclusion传递复选框的指令,则满足我的所有要求。但是,当我单击“奇特”切换开关时,我无法想办法改变我的转换复选框输入的状态。
这是我的指令的简化版本:
app.directive('toggleSwitch',function(){
return {
restrict: 'AE',
replace: true,
transclude: true,
template: '<span class="switch" ng-click="toggleSwitch()"><span class="fancySwitch"></span><span ng-transclude></span></span>',
link: function(scope, elem){
scope.toggleSwitch = function(){
//modify my fancy switch via classes (I can handle this part)
//How do I modify the status of my checkbox? (this needs to toggle the status of the checkbox - checked or no)
};
}
};
});
编辑:我找到了一种方法来实现我的目标而不进行翻译(见下文)。
我已更新问题标题以更好地反映我的初步挑战,并在下面添加解决方案作为答案。
答案 0 :(得分:0)
我发现如果我保留原始输入并将指令应用于它,那么我可以使用ngModel控制器来完成我想要的任务:
我使用before()
添加自定义开关,然后向其添加单击事件侦听器。通过不替换指令模板中的输入,输入仍然是父窗体的一部分,并且是父窗口范围的一部分(使我能够访问元素和整个窗体的验证属性)。
单击开关后,我可以使用$setViewValue
切换复选框状态,我不必担心处理ng-true-value
,因为这样做。 $setViewValue
将“神奇地”导致父表单运行验证并更改“原始”状态等。我还可以对输入本身执行其他操作,例如$setDirty()
和$validate()
,我无法做(我能找到)使用翻译。此外,没有翻译,我的指令在视图上更精简。
<input toggle-switch ts-true-label="Affirmative" ts-false-label="Negative" type="checkbox" name="isApproved" ng-model="sampleForm.isApproved" ng-true-value="'Yes'" ng-false-value="'No'">
然后是指令:
app.directive('toggleSwitch',function($timeout){
return {
restrict: 'AE',
replace: false,
require: '?ngModel',
link: function (scope, elem, attrs, ngModel){
var switchElem;//the new switch element
//Hide the checkbox
elem.css({display: 'none'});
/**
* Toggle the switch. This function is called on the click event on the generated toggle switch
*/
var toggleTheSwitch = function(){
//toggle the checkbox
if(ngModel.$viewValue === true){
ngModel.$setViewValue(false);//note: setting view value sets the value for the view (ie, checks the checkbox, etc, then sets appropriate model view for us, also the form validates for us)
switchElem.removeClass('checked');
}
else{
ngModel.$setViewValue(true);
switchElem.addClass('checked');
}
//run all checks and set appropriate status for this individual elem
ngModel.$setDirty();
ngModel.$setTouched();
ngModel.$validate();
ngModel.$render();
};
/**
* Creates and adds the switch html to the dom
*/
var createSwitch = function(){
if(switchElem){
switchElem.remove();
}
//Create the toggle switch
var switchHTML = '';
switchHTML += '<span class="switch' + (attrs.class ? ' ' + attrs.class : '') + ' ' + (ngModel.$viewValue ? 'checked' : '') +'" >';
switchHTML += '<span class="label checkedLabel">'+(attrs.tsTrueLabel ? attrs.tsTrueLabel: '')+'</span>';
switchHTML += '<span class="label uncheckedLabel">'+(attrs.tsFalseLabel ? attrs.tsFalseLabel: '')+'</span>';
switchHTML += '<small></small>';
switchHTML += '</span>';
switchElem = angular.element(switchHTML);//create angular jqlite object
elem.before(switchElem);//add new stuff before the checkbox
};
//After the directive is done loading, we can access ngModel controller
$timeout(function() {
//create the switch
createSwitch();
//set onclick event
switchElem.on('click', function(){
toggleTheSwitch();
});
});
}
};
});
对于其他任何人,请随意使用它。当然,你必须自己创建css。