Angularjs 引导开关停止使用角度布线

Angularjs 引导开关停止使用角度布线,angularjs,twitter-bootstrap,Angularjs,Twitter Bootstrap,我刚刚开始学习Angular,并为我的第一个应用程序设置了Angular路由 我有一个shell页面和一些子页面,例如products.html、help.html等 子页面包含带有引导开关和验证的表单,由于某些原因,这些表单会停止工作(开关显示为常规复选框,验证不会运行-请注意,我没有使用Angular JS) 但是,如果将相同的代码直接放在shell页面中,则可以正常工作 如何使子页面的行为与shell页面中的代码完全相同 基本上,如果我在help.html子页面之一的表单中有以下代码:

我刚刚开始学习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页面上的a中显示)或直接放置在shell页面HTML中的somw代码中发生的事情有什么区别呢。

我假设您使用的是插件

我还假设您正在通过执行以下操作初始化shell页面上的开关:

$(function () {
    $('input[type="checkbox"]').bootstrapSwitch();
});
问题是,它只会将引导开关插件应用于它在第一次页面加载时找到的复选框,而不是在您更改
ng视图
元素中的页面之后

我建议您改为创建一个简单的AngularJS指令,将引导开关插件应用于复选框。这样做的原因是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>
然后可以在标记中省略
bs开关
属性

请参阅my(对于角度示例,Plunkr是比JSFIDLE更好的工具,它允许您创建多个HTML、CSS和JS文件)

编辑2:正如马克所指出的,如果最初选中复选框,它将被破坏。以下是该指令的固定版本(以及:

//作为将应用于所有复选框输入的元素指令:
// 
app.directive('input',function(){
返回{
限制:'E',
要求:'ngModel',
链接:函数(范围、元素、属性、ngModelCtrl){
if(attrs.type=='checkbox'&&!Object.hasOwnProperty(attrs,'bsSwitch')){
$(元素).bootstrapSwitch({
onSwitchChange:功能(事件、状态){
作用域$apply(函数(){
ngModelCtrl.$setViewValue(状态);
});
}
});
var dereg=scope.$watch(函数(){
返回ngModelCtrl.$modelValue;
},函数(newVal){
$(元素).bootstrapSwitch('state',!!newVal,true);
德里格();
});
}
}
}
});

您能创建一个JSFIDLE吗?这样我们就可以看到您到目前为止所做的尝试。我试图设置一个JSFIDLE,但尽管我包含了所有外部库,但我无法让它工作。另外,我不知道如何在那里放置几个HTML文件。这是非工作的小提琴:我还编辑了我的原始帖子。请注意,我正在为一个特定的网站构建一个应用程序,该应用程序使用基于twitter引导的自己的框架,因此我不得不使用它们的内置验证等。我的问题是如何让子页面中的代码以与放置在shell页面中的代码相同的方式运行(因为这很好),您可能是对的。我应该把指令放在哪里?没有让它发挥作用。我得到“TypeError:无法读取未定义的属性'indexOf'。然而,我以交换机为例,我希望避免在这里和那里有很多黑客来让事情正常工作。我还发现验证插件也不起作用,因为我正在开发一个自定义框架(尽管基于引导),所以很难忽略我以后可能遇到的问题。因此,我正试图为我的应用程序找到一个长远来说更加可靠的设置。我编辑了我的答案,以纳入我相信你正在努力实现的目标。我还修复了初始指令代码中的错误,并链接到了Plunkr上的一个工作示例。非常感谢!它可以工作,但在我的环境中,它的行为略有不同,可能是因为它是一个自定义版本的引导(我正在为特定环境构建应用程序,并且被迫使用它们的设置)。似乎角度路由会让我陷入这类问题(我在jQuery验证方面也有问题)等等。使用选项卡而不是路由是否效率更高?有没有一种方法可以简单地将一个参数传递给另一个选项卡,比如说,如果我有一个产品列表,我想打开“editProduct”选项卡并在DB中获取关于productID 123的信息?很好的解决方案,不幸的是,如果模型最初设置为true@Mark该死,你说得对。我最后试了一下,现在应该好多了。
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);
              });
            }
          });
      }
    }
});
// 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();
        });
      }
    }
  }
});