我尝试使用prettyCheckbox插件将样式应用于我的复选框。对于那些不知道插件工作的人来说,隐藏原始复选框并显示另一个样式对象。我创建了一个指令,为每个复选框实例化插件。
点击假复选框的插件设置了真实输入元素的属性并调用了更改 - 但这似乎并不能更新模型:
input.prop('checked', true).change();
我稍微修改了prettyCheckbox插件,因此使用click事件更改原始复选框以更新模型:
input.trigger('click');
这样可以正常工作,但是复选框似乎总是具有您期望的完全相反的值:如果未选中复选框,则为true;如果选中复选框,则为false。我似乎无法弄清楚为什么会这样。我创建了一个plunkr来向您展示正在发生的事情:
http://plnkr.co/edit/YVq2is0khGgLRWbHk2aB?p=preview
提前感谢任何帮助之手:)
答案 0 :(得分:1)
input.trigger('click')
。由于JavaScript是单线程的,因此事件循环一次只能处理一个事件并且事件已经被处理,因此只要事件队列空闲,就会处理此事件。在您的情况下,当您的“点击”事件可以处理时,它是在角度完成运行摘要周期之后。这意味着在实际单击复选框之前,angular已经完成了处理,当复选框单击完成时,angular忽略它,因为它将“showRedBox”值视为干净(非脏)。直到您再次单击漂亮的复选框上,angular再次查看“showRedBox”,将其当前值与旧值进行比较,识别它是脏的,并更新DOM。当然,到完成时,您的复选框没有再次更改状态,因此它不同步。调用$scope.$apply()
或$scope.$digest()
在这种情况下无济于事,因为angular已经认为“showRedBox”是干净的。您必须首先修改角度的数据,以便将“showRedBox”值识别为脏,只有在您有权访问范围时才能执行此操作(您不能)。
解决方案:使用scope.showRedBox = fakeCheckable.hasClass("checked");
代替input.trigger('click')
直接修改“showRedBox”值。此解决方案将要求您修改插件的范围以使其落在指令的闭包内。
答案 1 :(得分:1)
是的,所以我发现这个jsfiddle确实帮助我在不使用漂亮的复选框插件的情况下解决问题:
http://jsfiddle.net/evaneus/z9rge/
正如詹姆斯在答案中提到的,该指令需要访问控制器:
angular.module('buttonToggle', []).directive('buttonToggle', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function($scope, element, attr, ctrl) {
var classToToggle = attr.buttonToggle;
element.bind('click', function() {
var checked = ctrl.$viewValue;
$scope.$apply(function(scope) {
ctrl.$setViewValue(!checked);
});
});
$scope.$watch(attr.ngModel, function(newValue, oldValue) {
newValue ? element.addClass(classToToggle) : element.removeClass(classToToggle);
});
}
};
});
<p>
<input id="gradeCheck" type="checkbox" ng-model="myModel['A']"> A
<input type="checkbox" ng-model="myModel['B']"> B
<input type="checkbox" ng-model="myModel['C']"> C
<input type="checkbox" ng-model="myModel['D']"> D
</p>
<p>
<button button-toggle="active" class="btn" ng-model="myModel['A']">A</button>
<button button-toggle="active" class="btn" ng-model="myModel['B']">B</button>
<button button-toggle="active" class="btn" ng-model="myModel['C']">C</button>
<button button-toggle="active" class="btn" ng-model="myModel['D']">D</button>
</p>
然后我只需按照我想要的方式设置按钮的样式,并且没有活动的样式,并且所有工作都很好:)