2013-10-25 23 views
0

我用this guide來創建自定義dropdown list而不是select(所有瀏覽器都不支持定製select)。 這種方式結合了一些CSS和jQUery。我爲這個dropdown list創建了一個directive,一切似乎都正常工作,直到我試圖在ng-view內部實現它,我的解析template根本無法使用我的解決方案(directive)。爲什麼自定義下拉列表指令不適用於ngView?

My code - plunk - 在我的普拉克你可以看到index.html中工作dropdown list和未在temp.html(呈現爲ngView)工作dropdown list 兩個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-視圖:

<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; 
       } 
      } 
     } 
    }; 
}); 

對於這個問題,或多或少有類似的問題,但他們對我沒有多大幫助。

回答

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">東西)

最後角需要找到的jQuery爲了上述elem讓所有jQuery方法。

所以最終更改:包括jQuery <script>以上有角度。

見分叉普拉克:http://plnkr.co/edit/ffltLZit27EGpW13RmRe?p=preview


現在不得不說上面的,我想你沒有使用正確的角度。我知道,我有jQuery背景,並且在開始時傾向於使用jQuery來做所有事情。我建議的更改:

  • 不要使用jQuery事件(除非有很好的理由 - 在這種情況下)。使用指令的模板和ng-click而不是$(...).on("click")。 (請注意,如果jQuery點擊修改了模型,您將不得不使用$scope.$apply()。)
  • $(document).click(function() {部分將在文檔上安裝N個事件處理程序,每個選擇一個。實際上只需要1個,所以我會將它放在link函數之外。最有可能的指令定義函數內部:

    webApp.directive('dropdown', function() { 
        $(document).click(function() { 
         ... 
        }); 
        return { 
         ... 
        }; 
    }); 
    
  • 使用$(function() {...}是不必要的。文檔將在應用指令時加載。

+0

你plunk沒有完全工作。選定的選項不會成爲活動的選項 – Canttouchit

+0

我按照您的意見進行管理以創建適用的內容:http://plnkr.co/edit/TBrlW2kU5oi0xDkEZPe3?p=preview – Canttouchit