0

我使用本指南创建了一个dropdown list没有的自定义selectselect并非所有浏览器都支持自定义)。这种方式结合了一些CSS和jQuery。directive我为此创建了一个dropdown list,一切似乎都可以正常工作,Angular直到我尝试在内部实现它ng-view,我的渲染template根本不适用于我的解决方案(directive)。

我的代码 - plunk - 在我的 plunk 中,您将能够看到dropdown listindex.html 中的dropdown list工作以及 temp.html 中不工作的(渲染到ngView)两者都dropdown lists使用相同的directive.

我的 index.html:

  <body ng-controller='VotesCtrl'>

    <p>This is working (no ng-view):</p>
    <div dropdown id="dd" class="wrapper-dropdown-3" tabindex="1">
      <i class="arrow"></i>
      <span>{{statuses[0]}}</span>
      <ul class="dropdown">
          <li ng-repeat="status in statuses"><a href="#">{{status}}</a></li>
      </ul>
    </div>

    <br />
    <br />
    <br />
    <br />
    <br />
    <br />
    <br />
    <br />

    <div class="content" ng-view></div>  
   </body>

我的 temp.html 由路由器渲染到 ng-view:

<p>This is from ng-View, not working:</p>

<div dropdown id="dd" class="wrapper-dropdown-3" tabindex="1">
  <i class="arrow"></i>
  <span>{{statuses[0]}}</span>
  <ul class="dropdown">
        <li ng-repeat="status in statuses"><a href="#">{{status}}</a></li>
  </ul>
</div> 

我的代码(包括directive):

// Code goes here


var webApp = angular.module('webApp', []);


//router logic
webApp.config(['$routeProvider', function($routeProvider) {
    $routeProvider.
        when('/', {
            templateUrl: 'temp.html',
            controller: 'tempCtrl'
        })

        .otherwise({redirectTo: '/'});
}]);

//controllers

webApp.controller ('VotesCtrl', function ($scope) {
    $scope.statuses = ["Approved","Pending","Trash","Spam"];
});


webApp.controller ('tempCtrl', function ($scope) {
    $scope.statuses = ["Approved","Pending","Trash","Spam"];
});
//services



//directive
webApp.directive('dropdown', function() {
    return {
        restrict: 'A',
        link: function() {
          $(function() {

              var dd = new DropDown( $('#dd') );

              $(document).click(function() {
                  // all dropdowns
                  $('.wrapper-dropdown-3').removeClass('active');
              });

          });

          function DropDown(el) {
              this.dd = el;
              this.placeholder = this.dd.children('span');
              this.opts = this.dd.find('ul.dropdown > li');
              this.val = '';
              this.index = -1;
              this.initEvents();
          }
          DropDown.prototype = {
              initEvents : function() {
                  var obj = this;

                  obj.dd.on('click', function(event){
                      $(this).toggleClass('active');
                      return false;
                  });

                  obj.opts.on('click',function(){
                      var opt = $(this);
                      obj.val = opt.text();
                      obj.index = opt.index();
                      obj.placeholder.text(obj.val);
                  });
              },
              getValue : function() {
                  return this.val;
              },
              getIndex : function() {
                  return this.index;
              }
          } 
        }
    };
});

对于这个问题,或多或少有类似的问题,但它们对我帮助不大。

4

1 回答 1

2

出现错误:DropDown 上没有方法“initEvents”。之所以在 Javascript 中首先定义函数和变量,然后执行代码。所以在link函数DropDown中定义了函数,但里面的代码在定义原型的代码之前$(function() {...运行。DropDown

所以第一个变化就是把$(function() {...代码放在原型代码下面。

然后你用 id 初始化一些东西dd。这个 id 有两件事,所以 jQuery 会混淆。没有理由这样做;使用链接函数提供的元素参数。

所以第二个变化:

link: function(scope, elem, attrs) {
    ...
    var dd = new DropDown(elem); // NOT $('#dd')
    ...
 }

(既然你在它,更正或删除的<div id="dd">东西)

最后 Angular 需要找到 jQuery 以便elem上面拥有所有 jQuery 方法。

<script> 所以最后的改变:在Angular上包含 jQuery 。

见分叉 plunk:http ://plnkr.co/edit/ffltLZit27EGpW13RmRe?p=preview


现在说了以上,我认为你没有正确使用 Angular。我知道,我有 jQuery 背景,并且一开始倾向于用 jQuery 做所有事情。我建议的更改:

  • 不要使用 jQuery 事件(除非有一个非常好的理由 - 在这种情况下不是)。为指令使用模板,ng-click而不是$(...).on("click"). (请记住,如果 jQuery click 修改了模型,您将不得不使用$scope.$apply().)
  • $(document).click(function() {部分将在文档上安装 N 个事件处理程序,每个选择一个。实际上只需要 1,所以我将它放在link函数之外。最有可能在指令定义函数中:

    webApp.directive('dropdown', function() {
        $(document).click(function() {
            ...
        });
        return {
            ...
        };
    });
    
  • 使用$(function() {...}是不必要的。应用指令时,文档将被加载。

于 2013-10-25T07:43:45.270 回答