我刚刚开始学习Angular并为我的第一个应用程序设置了Angular路由。
我有一个shell页面和一些子页面,例如products.html,help.html等
子页面包含带有引导开关和验证的表单,由于某种原因停止工作(交换机呈现为常规复选框,验证不运行 - 请注意我没有使用Angular JS。)
但是,如果将相同代码直接放在shell页面中,则可以正常工作。
如何使子页面的行为与shell页面中的代码完全相同?
基本上,如果我的子页面help.html中有以下代码:
<div class="form-group">
<label for="active">My checkbox<br />
<div class="switch">
<input type="checkbox" value="1" id="active" name="active">
</div>
</div>
...交换机无法正确呈现,但如果我将代码直接移动到shell页面,则会正确呈现。
那么子页面(在shell页面上显示)或直接放在shell页面HTML中的somw代码会发生什么不同。
答案 0 :(得分:8)
我假设您使用的是this Bootstrap Switch插件。
我还假设您正在通过执行以下操作来初始化在shell页面上工作的开关:
$(function () {
$('input[type="checkbox"]').bootstrapSwitch();
});
这个问题是它只会将引导开关插件应用到它在第一页加载时找到的复选框,而不是在ng-view
元素中更改页面之后。
我建议你做的是创建一个简单的AngularJS指令,将bootstrap switch插件应用于复选框。这将起作用的原因是Angular将在每次更改页面时编译视图的内容,并且将运行找到的所有指令的link()
函数。因此,您的复选框,如果他们使用此新指令,将始终正确应用插件。
指令可以简单如下:
app.directive('bsSwitch', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
$(element).bootstrapSwitch({
onSwitchChange: function(event, state) {
scope.$apply(function() {
ngModelCtrl.$setViewValue(state);
});
}
});
}
}
});
然后将视图中的标记更改为:
<div class="form-group">
<label for="active">My checkbox</label>
<br />
<div class="switch">
<input type="checkbox" value="1" id="active" name="active" bs-switch>
</div>
</div>
编辑:如果您希望将引导开关应用于应用程序上的所有复选框而无需其他属性,则可以创建一个适用于所有<input>
,然后检查它们是否是复选框。
像这样:
app.directive('input', function() {
return {
restrict: 'E',
require: 'ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
if (attrs.type === 'checkbox')
$(element).bootstrapSwitch({
onSwitchChange: function(event, state) {
scope.$apply(function() {
ngModelCtrl.$setViewValue(state);
});
}
});
}
}
});
然后您可以省略标记中的bs-switch
属性。
请参阅我的working Plunkr example(对于Angular示例,Plunkr是比jsFiddle更好的工具,并允许您创建多个HTML,CSS和JS文件)。
编辑2:正如Mark指出的那样,如果最初选中该复选框,它就会被破坏。以下是该指令的固定版本(以及updated Plunkr):
// As an element directive that will apply to all checkbox inputs:
// <input type="checkbox" ng-model="blah">
app.directive('input', function() {
return {
restrict: 'E',
require: 'ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
if (attrs.type === 'checkbox' && !Object.hasOwnProperty(attrs, 'bsSwitch')) {
$(element).bootstrapSwitch({
onSwitchChange: function(event, state) {
scope.$apply(function() {
ngModelCtrl.$setViewValue(state);
});
}
});
var dereg = scope.$watch(function() {
return ngModelCtrl.$modelValue;
}, function(newVal) {
$(element).bootstrapSwitch('state', !! newVal, true);
dereg();
});
}
}
}
});