0
回答
angularjs array改变,但ng-repeat没有刷新
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

angular菜鸟,在网上下载了一个自定义指令,实现ionic 的slide tab scroll结合,在ion-slide使用ng-repeat指令,在controller实现对数组的操作,但是数组发生改变,ng-repeat却没有更新。对myTags里的同一个标签,先调用remove()后再调用add(),会报重复错误。涉及的源码如下:

index.html

<ion-slide-box id="slide_box" show-pager="false" ion-slide-tabs>
      <ion-slide ng-repeat="tag in myTags track by $index" ion-slide-tab-label=“{{tag.tagname}}”>

                .........
              </ion-slide>
    </ion-slide-box>

service.js

function getTags() {
      var url = xxxxxxx;

      return $http({
          method: 'GET',
          url: url
        })
        .success(function(res) {
          //console.log('is collect success');
        })
        .error(function(msg, code) {
          console.log('tag error.....', code);
        });
    }

indexCtrl.js

    $scope.tags = [];
    $scope.myTags = [];
    $scope.moreTags = [];

   function getTags(){
      ds.getTags()
      .then(function(res){
        var traTags = [];
        var l = res.data.length;
        $scope.tags=res.data;
        traTags = angular.copy($scope.tags);
        $scope.myTags = traTags.splice(0,l/2);
        $scope.moreTags = traTags;
      });
    }

..........

function remove(index){
      if(!$scope.lock){
        $scope.moreTags.unshift($scope.myTags[index]);
        $scope.myTags.splice(index,1);
      }else{
        return;
      }
    }

function add(index){
      $scope.myTags.push($scope.moreTags[index]);
      $scope.moreTags.splice(index,1);
    }

slidingTabsDirective.js

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 = '<li ng-repeat="(key, value) in tabs" ng-click="onTabTabbed($event, {{key}})" class="slider-slide-tab" ng-bind-html="value"></li>';

        if (options.slideTabsScrollable) {
          //alert(options.slideTabsScrollable)

          ionicScrollDelegateID = "ion-slide-tabs-handle-" + Math.floor((Math.random() * 10000) + 1);
          tabsBar = angular.element('<ion-scroll delegate-handle="' + ionicScrollDelegateID + '" class="slidingTabs" direction="x" scrollbar-x="false"><ul>' + tabItems + '</ul> <div class="tab-indicator-wrapper"><div class="tab-indicator"></div></div> </ion-scroll>');
        } else {

          tabsBar = angular.element('<div class="slidingTabs"><ul>' + tabItems + '</ul> <div class="tab-indicator-wrapper"><div class="tab-indicator"></div></div> </div>');

        }


        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 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) {
        ionicSlideBoxDelegate.slide(index);
        slideToCurrentPosition();
      };

      scope.tabs = [];

      scope.addTabContent = function($content) {

        $content = $content.replace(/\“/g, '').replace(/\”/g, '');
        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 scrollDiv = slider[0].getElementsByClassName("slider-slide");

        var currentSlideIndex = ionicSlideBoxDelegate.currentIndex();
        var currentSlide = angular.element(scrollDiv[currentSlideIndex]);
        var currentSlideLeftOffset = currentSlide.css('-webkit-transform').replace(/[^0-9\-.,]/g, '').split(',')[0];

        var targetSlideIndex = (currentSlideIndex + 1) % scrollDiv.length;
        if (currentSlideLeftOffset > slider.prop("offsetLeft")) {
          targetSlideIndex = currentSlideIndex - 1;
          if (targetSlideIndex < 0) {
            targetSlideIndex = scrollDiv.length - 1;
          }
        }
        var targetSlide = angular.element(scrollDiv[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);
    }
  };
}]);

请问应该怎么修改?谢谢!

<无标签>
举报
elysium09
发帖于9个月前 0回/321阅
顶部