2017-03-14 2 views
1

コントローラーを持つこの指令がありました。それはこのように見えた:controllerAs、bindToController and watches

.directive('pkSlider', ['$timeout', function ($timeout) { 
    return { 
     restrict: 'A', 
     scope: { 
      question: '=pkSlider', 
      options: '=', 
      onSelect: '&' 
     }, 
     controller: 'PKSliderController', 
     templateUrl: function (element, attrs) { 
      if (attrs.type === 'image') 
       return 'assets/templates/directives/pk-image.html'; 

      return 'assets/templates/directives/pk-slider.html'; 
     }, 
     link: function (scope, element, attrs, controller) { 

      // Get our visible answers 
      scope.answers = controller.getVisibleAnswers(scope.question.answers); 

      // Increase the answers if they are less than the slides to show 
      if (scope.answers.length <= scope.options.slidesToShow) 
       scope.answers = scope.answers.concat(scope.answers); 

      // Watch our answers 
      scope.$watch('answers', function (answers) { 

       // When we have our answers 
       if (answers.length) { 

        // Extend our options 
        angular.extend(scope.options, { 
         event: { 

          // Set our first slide and sort/filter our products 
          init: function (event, slick) { 

           // Get the actual index stored in the answer 
           var index = scope.answers[slick.currentSlide].index; 

           // Set our current slide to the physical current slide, this is for the images to be shown 
           scope.currentSlide = slick.currentSlide; 

           // Invoke our methods using the answer index 
           controller.afterChange(scope.question, index); 
           scope.onSelect({ index: index, direction: slick.direction }); 
          }, 

          // Set our current slide and sort/filter our products 
          afterChange: function (event, slick, currentSlide) { 

           // Get the actual index stored in the answer 
           var index = scope.answers[currentSlide].index; 
           // Set our current slide to the physical current slide, this is for the images to be shown 
           scope.currentSlide = currentSlide; 

           // Invoke our methods using the answer index 
           controller.afterChange(scope.question, index); 
           scope.onSelect({ index: index, direction: slick.direction }); 
          } 
         } 
        }); 

        // We have loaded 
        scope.loaded = true; 
       } 
      }); 
     } 
    }; 
}]); 

とコントローラは、このように見えた:私はangular style guideに応じて自分のコードを変換すると、私は存在していたが実現しなかったディレクティブのための新しいオプションを発見された

.controller('PKSliderController', ['$timeout', '$interval', 'TrackingProvider', 'AnswerProvider', function ($timeout, $interval, tracking, provider) { 
    var self = this, 
     timer, 
     setActiveImage = function (answers, activeIndex) { 

      // If we have a current timer running, cancel it 
      if (timer) 
       $timeout.cancel(timer); 

      // For each answer 
      answers.forEach(function (answer, index) { 

       // Get our images 
       var images = answer.images; 

       // If we have an image 
       if (images) { 

        // Get our image 
        var image = images[0]; 

        // If we are active 
        if (index === activeIndex) { 

         // For each text 
         image.imageText.forEach(function (text) { 
          text.active = false; 

          // Activate our text after the delay 
          $interval(function() { 
           text.active = true; 
          }, text.delay, 1); 
         }); 
        } 
       } 
      }); 
     }; 

    // Get our answers 
    self.getVisibleAnswers = provider.getVisible; 

    // Updates the question with your selected answer 
    self.afterChange = function (question, answerIndex) { 

     // Get our answer 
     var answers = question.answers, 
      answer = answers[answerIndex]; 

     // Set our active image 
     setActiveImage(answers, answerIndex); 

     // This is for the last step, because some options might not actually be available 
     if (answer) { 

      // Set our selected answer 
      question.radioChoice = answer.text; 
     } 
    }; 
}]) 

bindToControllerと呼ばれます。だから私はこれを実装しようとしています。 私はこれに私のディレクティブを変換しました:

すでに多くのクリーナーです
(function() { 
    'use strict'; 

    angular.module('widget.directives').directive('pkSlider', pkSlider); 

    pkSlider.$inject = ['$timeout']; 

    function pkSlider($timeout) { 
     return { 
      restrict: 'A', 
      scope: { 
       question: '=pkSlider', 
       options: '=', 
       onSelect: '&' 
      }, 
      controller: 'PKSliderController', 
      controllerAs: 'controller', 
      bindToController: true, 
      templateUrl: getTemplate 
     }; 

     function getTemplate(element, attrs) { 
      if (attrs.type === 'image') 
       return 'app/directives/pkImage.html'; 

      return 'app/directives/pkSlider.html'; 
     }; 
    } 
})(); 

。 私はその後、私のコントローラに変換しようとしています:

(function() { 
    'use strict'; 

    angular.module('widget.directives').controller('PKSliderController', PKSliderController); 

    PKSliderController.$inject = ['$scope', '$timeout', '$interval', 'answerProvider']; 

    function PKSliderController($scope, $timeout, $interval, answerProvider) { 
     var self = this, 
      timer; 

     // Bindings 
     self.afterChange = afterChange; 
     $scope.$watch('controller.answers', watchAnswers); 

     // Init 
     init(); 

     function init() { 

      // Get our answersw 
      self.answers = answerProvider.getVisible(self.question.answers); 

      // Increase the answers if they are less than the slides to show 
      if (self.answers.length <= self.options.slidesToShow) 
       self.answers = self.answers.concat(self.answers); 
     }; 

     // Watches the answers for any changes 
     function watchAnswers(answers) { 

      // When we have our answers 
      if (answers.length) { 

       // Extend our options 
       self.options = angular.merge(self.options, { 
        event: { 

         // Set our first slide and sort/filter our products 
         init: function (event, slick) { 

          // Get the actual index stored in the answer 
          var index = self.answers[slick.currentSlide].index; 

          // Set our current slide to the physical current slide, this is for the images to be shown 
          self.currentSlide = slick.currentSlide; 

          // Invoke our methods using the answer index 
          controller.afterChange(self.question, index); 
          self.onSelect({ index: index, direction: slick.direction }); 
         }, 

         // Set our current slide and sort/filter our products 
         afterChange: function (event, slick, currentSlide) { 

          // Get the actual index stored in the answer 
          var index = self.answers[currentSlide].index; 
          // Set our current slide to the physical current slide, this is for the images to be shown 
          self.currentSlide = currentSlide; 

          // Invoke our methods using the answer index 
          controller.afterChange(self.question, index); 
          self.onSelect({ index: index, direction: slick.direction }); 
         } 
        } 
       }); 

       // We have loaded 
       self.loaded = true; 
      } 
     }; 

     // Updates the question with your selected answer 
     function afterChange(question, answerIndex) { 

      console.log('we are changing'); 

      // Get our answer 
      var answers = question.answers, 
       answer = answers[answerIndex]; 

      // Set our active image 
      setActiveImage(answers, answerIndex); 

      // This is for the last step, because some options might not actually be available 
      if (answer) { 

       // Set our selected answer 
       question.radioChoice = answer.text; 
      } 
     }; 

     // Sets the active image 
     function setActiveImage(answers, activeIndex) { 

      // If we have a current timer running, cancel it 
      if (timer) 
       $timeout.cancel(timer); 

      // For each answer 
      answers.forEach(function (answer, index) { 

       // Get our images 
       var images = answer.images; 

       // If we have an image 
       if (images) { 

        // Get our image 
        var image = images[0]; 

        // If we are active 
        if (index === activeIndex) { 

         // For each text 
         image.imageText.forEach(function (text) { 
          text.active = false; 

          // Activate our text after the delay 
          $interval(function() { 
           text.active = true; 
          }, text.delay, 1); 
         }); 
        } 
       } 
      }); 
     }; 
    }; 
})(); 

をしかし、私は時計の問題を抱えています。オプションを変更するようには見えません。私は私の見解にオプションを追加し、それがこの返します

{ "slidesToShow":1、 "centerPadding":0、 "イベント":{}}

面白いです

、なぜなら

{slidesToShow:1、centerPadding:0}

だから、ビットを更新しているが、実際にイベントオブジェクトにメソッドを結合しない私は今まで、これを通過します。なぜ誰かがこれを動作させる方法を知っていますか?あなたは、それは以下のようにthisまたはselfを結合することによって、コントローラインスタンス上で直接利用できるようちょうどself.answersを上監視する必要があり

+0

問題を解決するかどうか、以下の回答を確認してください。 – Abhishek

答えて

0

それがすべてを正しく作成していた、私のせいでした。私はそれを "コントローラ"にバインドしていませんでした。

2

$scope.$watch(angular.bind(self, function() { 
    return self.answers; 
}), watchAnswers); 
+0

私はそうは思わない。 'if(answers.length)'の後にコンソールログを置き、それに達しました。 – r3plica

+0

'controller.answers'を見てみると、' $ scope.controller.answers'を見るためのルックです。したがって、コンテキストをバインドする必要があります – Abhishek

関連する問題