javascript - angularjs指令代码研读,学到什么程度才能写出这样的指令?
PHPz
PHPz 2017-04-11 12:35:10
[JavaScript讨论组]

var slidingTabsDirective = angular.module("ionic").directive('ionSlideTabs', ['$timeout', '$compile', '$interval', '$ionicSlideBoxDelegate', '$ionicScrollDelegate', '$ionicGesture', function($timeout, $compile, $interval, $ionicSlideBoxDelegate, $ionicScrollDelegate, $ionicGesture) {
    return {
        require: "^ionSlideBox",
        restrict: 'A',
        link: function(scope, element, attrs, parent) {

            var ionicSlideBoxDelegate;
            var ionicScrollDelegate;
            var ionicScrollDelegateID;

            var slideTabs;
            var indicator;

            var slider;
            var tabsBar;

            var options = {
                "slideTabsScrollable": true
            }


            var init = function () {

                if(angular.isDefined( attrs.slideTabsScrollable ) && attrs.slideTabsScrollable === "false" ) {
                    options.slideTabsScrollable = false;
                }

                var tabItems = '
  • '; if(options.slideTabsScrollable) { ionicScrollDelegateID = "ion-slide-tabs-handle-" + Math.floor((Math.random() * 10000) + 1); tabsBar = angular.element('
      ' + tabItems + '

    '); } else { tabsBar = angular.element('

      ' + tabItems + '

    '); } slider = angular.element(element); var compiled = $compile(tabsBar); slider.parent().prepend(tabsBar); compiled(scope); //get Tabs DOM Elements indicator = angular.element(tabsBar[0].querySelector(".tab-indicator")); //get the slideBoxHandle var slideHandle = slider.attr('delegate-handle'); var scrollHandle = tabsBar.attr('delegate-handle'); ionicSlideBoxDelegate = $ionicSlideBoxDelegate; if (slideHandle) { ionicSlideBoxDelegate = ionicSlideBoxDelegate.$getByHandle(slideHandle); } if(options.slideTabsScrollable) { ionicScrollDelegate = $ionicScrollDelegate; if (scrollHandle) { ionicScrollDelegate = ionicScrollDelegate.$getByHandle(scrollHandle); } } addEvents(); setTabBarWidth(); slideToCurrentPosition(); }; var addEvents = function() { ionic.onGesture("dragleft", scope.onSlideMove ,slider[0]); ionic.onGesture("dragright", scope.onSlideMove ,slider[0]); ionic.onGesture("release", scope.onSlideChange ,slider[0]); } var setTabBarWidth = function() { if( !angular.isDefined(slideTabs) || slideTabs.length == 0 ) { return false; } tabsList = tabsBar.find("ul"); var tabsWidth = 0; angular.forEach(slideTabs, function (currentElement,index) { var currentLi = angular.element(currentElement); tabsWidth += currentLi[0].offsetWidth; }); if(options.slideTabsScrollable) { angular.element(tabsBar[0].querySelector(".scroll")).css("width", tabsWidth + 1 + "px"); } else { slideTabs.css("width",tabsList[0].offsetWidth / slideTabs.length + "px"); } slideToCurrentPosition(); }; var addTabTouchAnimation = function(event,currentElement) { var ink = angular.element(currentElement[0].querySelector(".ink")); if( !angular.isDefined(ink) || ink.length == 0 ) { ink = angular.element(""); currentElement.prepend(ink); } ink.removeClass("animate"); if(!ink.offsetHeight && !ink.offsetWidth) { d = Math.max(currentElement[0].offsetWidth, currentElement[0].offsetHeight); ink.css("height", d + "px"); ink.css("width", d + "px"); } x = event.offsetX - ink[0].offsetWidth / 2; y = event.offsetY - ink[0].offsetHeight / 2; ink.css("top", y +'px'); ink.css("left", x +'px'); ink.addClass("animate"); } var slideToCurrentPosition = function() { if( !angular.isDefined(slideTabs) || slideTabs.length == 0 ) { return false; } var targetSlideIndex = ionicSlideBoxDelegate.currentIndex(); var targetTab = angular.element(slideTabs[targetSlideIndex]); var targetLeftOffset = targetTab.prop("offsetLeft"); var targetWidth = targetTab[0].offsetWidth; indicator.css({ "-webkit-transition-duration": "300ms", "-webkit-transform":"translate(" + targetLeftOffset + "px,0px)", "width": targetWidth + "px" }); if (options.slideTabsScrollable && ionicScrollDelegate) { var scrollOffset = 40; ionicScrollDelegate.scrollTo(targetLeftOffset - scrollOffset,0,true); } slideTabs.removeClass("tab-active"); targetTab.addClass("tab-active"); } var setIndicatorPosition = function (currentSlideIndex, targetSlideIndex, position, slideDirection) { var targetTab = angular.element(slideTabs[targetSlideIndex]); var currentTab = angular.element(slideTabs[currentSlideIndex]); var targetLeftOffset = targetTab.prop("offsetLeft"); var currentLeftOffset = currentTab.prop("offsetLeft"); var offsetLeftDiff = Math.abs(targetLeftOffset - currentLeftOffset); if( currentSlideIndex == 0 && targetSlideIndex == ionicSlideBoxDelegate.slidesCount() - 1 && slideDirection == "right" || targetSlideIndex == 0 && currentSlideIndex == ionicSlideBoxDelegate.slidesCount() - 1 && slideDirection == "left" ) { return; } var targetWidth = targetTab[0].offsetWidth; var currentWidth = currentTab[0].offsetWidth; var widthDiff = targetWidth - currentWidth; var indicatorPos = 0; var indicatorWidth = 0; if (currentSlideIndex > targetSlideIndex) { indicatorPos = targetLeftOffset - (offsetLeftDiff * (position - 1)); indicatorWidth = targetWidth - ((widthDiff * (1 - position))); } else if (targetSlideIndex > currentSlideIndex) { indicatorPos = targetLeftOffset + (offsetLeftDiff * (position - 1)); indicatorWidth = targetWidth + ((widthDiff * (position - 1))); } indicator.css({ "-webkit-transition-duration":"0ms", "-webkit-transform":"translate(" + indicatorPos + "px,0px)", "width": indicatorWidth + "px" }); if (options.slideTabsScrollable && ionicScrollDelegate) { var scrollOffset = 40; ionicScrollDelegate.scrollTo(indicatorPos - scrollOffset,0,false); } } scope.onTabTabbed = function(event, index) { addTabTouchAnimation(event, angular.element(event.currentTarget) ); ionicSlideBoxDelegate.slide(index); slideToCurrentPosition(); } scope.tabs = []; scope.addTabContent = function ($content) { scope.tabs.push($content); scope.$apply(); $timeout(function() { slideTabs = angular.element(tabsBar[0].querySelector("ul").querySelectorAll(".slider-slide-tab")); slideToCurrentPosition(); setTabBarWidth() }) } scope.onSlideChange = function (slideIndex) { slideToCurrentPosition(); }; scope.onSlideMove = function () { var scrollp = slider[0].getElementsByClassName("slider-slide"); var currentSlideIndex = ionicSlideBoxDelegate.currentIndex(); var currentSlide = angular.element(scrollp[currentSlideIndex]); var currentSlideLeftOffset = currentSlide.css('-webkit-transform').replace(/[^0-9\-.,]/g, '').split(',')[0]; var targetSlideIndex = (currentSlideIndex + 1) % scrollp.length; if (currentSlideLeftOffset > slider.prop("offsetLeft")) { targetSlideIndex = currentSlideIndex - 1; if (targetSlideIndex < 0) { targetSlideIndex = scrollp.length - 1; } } var targetSlide = angular.element(scrollp[targetSlideIndex]); var position = currentSlideLeftOffset / slider[0].offsetWidth; var slideDirection = position > 0 ? "right":"left"; position = Math.abs(position); setIndicatorPosition(currentSlideIndex, targetSlideIndex, position, slideDirection); }; init(); }, controller: ['$scope',function($scope) { this.addTab = function($content) { $timeout(function() { if($scope.addTabContent) { $scope.addTabContent($content); } }); } }] }; }]); slidingTabsDirective.directive('ionSlideTabLabel', [ function() { return { require: "^ionSlideTabs", link: function ($scope, $element, $attrs, $parent) { $parent.addTab($attrs.ionSlideTabLabel); } } }]);
    PHPz
    PHPz

    学习是最好的投资!

    全部回复(4)
    ringa_lee

    directive,scope,controller先学好吧,先试着写些简单的,慢慢不就好了

    巴扎黑

    1.根据需求来直接实战,不要只看不写;
    2.最简单的,把你手里现在目前的小型组件全部转成AngularJS版本,只重写代码,而不是套一个AngularJS的壳子~~
    3.在重构代码的时候仔细学习自己忽略的知识点
    4.重构都没问题了,然后再开始根据Angular的一些特定来进行组件的优化

    上面其实每个步骤都能积攒一些经验~~

    对于Angular我觉得最重要的是深入理解和学习 如果使用数据来操作页面,而不是DOM~

    天蓬老师

    只是代码量多一些而已,仔细看来难度并不是很大。

    涉及到只是点主要是看指令注入了那些service,比如$compile指令需要加深理解。其他service都比较简单,

    再则重点关注 link函数中的几个参数(scope,element,attr,ctrl,transclude)在指令中的作用。

    还需要重点理解 controller函数在指令间通信的作用。

    总体来说,指令的东西需要持续学习,也需要小步快走,切不可想一下子都学会。 指令是angular的非常重要的一部分,也是angular实现组件化的重要一步。深入学习指令系统,对整个angular的学习都非常有好处。

    伊谢尔伦

    当你发现你要重复写很多次某种功能组件,或者一切组件不适合项目,你就想自己写了。其实真的很简单。并不是很难

    热门教程
    更多>
    最新下载
    更多>
    网站特效
    网站源码
    网站素材
    前端模板
    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送
    PHP中文网APP
    随时随地碎片化学习

    Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号