AngularJS控制器函数作用域在JQuery方法调用期间应用Timing

时间:2013-12-25 03:38:56

标签: angularjs

我正在AngularJS中编写一个练习应用程序,我列出了一些youtube图像,点击后我试图使用Sublime Youtube Video API在Bootstrap模态对话框中播放它们。但是,我面临以下问题:

  1. 除非我使用$ scope.apply() - 当我点击不同的YouTube图像时,选择中的更改不会被基于jquery的sublime api反映和拾取,因为sublime正在尝试检索youtube视频在AngularJS $范围值更新之前。

    所以,为了解决这个问题,我尝试添加$ scope.apply()。但是,如果我这样做,我在控制台日志中收到“错误:[$ rootScope:inprog] $ apply in progress”。

    我认为这在某种程度上与查询here有关,其中的讨论是关于将第三方插件与AngularJS结合并在应用$ scope更改后执行...但是,作为一个新手AngularJS我发现很难弄清楚如何重新设计我的代码!任何人都可以指导我出错的地方吗?或者我如何重写代码?

  2. 首次点击任何图片都不会播放任何内容。随后的点击工作正常。试图调试这是为什么......

  3. 以下是代码:(由于我使用sublime api播放视频,我无法为演示目的创建JS小提琴 - 对不起)

    控制器:

    myApp.controller("PlayerCtrl",
      function PlayerCtrl($scope,$log,$sce,trailers)
      {
         $scope.videos = trailers;
    
         $scope.selectedVideo = {
            ytId: "",
            imgSrc:"",
            width:"320",
            height:"300",
            title:"",
            lang: "",
            relDate: "",
            rating: ""
          };
    
         $scope.openVideo = function(video){
    
          $scope.selectedVideo = video;
          $scope.$apply();
    
          sublime.ready(function(){ // jquery based sublime video api
            console.log("Video Selected = " + JSON.stringify(video));
            $("#tfModal").modal({}); // invoking bootstrap modal
            $('#tfModal').on('shown.bs.modal', function (e) {
              console.log('preparing...');
              sublime.prepare('tfVideo', function(player) {
                player.play();
              });
            })
            $('#tfModal').on('hidden.bs.modal', function (e) {
              console.log('un preparing...');
              sublime.unprepare('tfVideo');
            })
          });
    
        };
      }
    );
    

    指令:

    myApp.directive("trailerList", function(){
      var htmlTemplate = "<div class='col-md-4 col-sm-6 col-xs-12'>" +
        " <div class='row top-buffer'>" +
        " </div>" +
        "<div style='position:relative;'>" +
        "  <div class='fader'>" +
        "    <a href='#' ng-click='onClick(video)'>" +
        "      <img width='{{video.width}}' height='{{video.height}}' alt='{{video.title}}' style='position: relative; z-index: 1;' src='{{video.imgSrc}}'/>" +
        "      <img src='images/play.png' style='position: absolute;left:40%; top:40%;z-index: 10;'/>" +
        "    </a>" +
        "  </div>" +
        "</div>";
    
      return {
        restrct: 'AE',
        scope: {
          video : "=",
          onClick : "&"
        },
        template: htmlTemplate
      };
    });
    
    myApp.directive("modalLayer", function(){
      var htmlTemplate =
      "<!-- Modal -->" +
        "<div class='modal fade' id='tfModal' tabindex='-1' role='dialog' aria-labelledby='myModalLabel' aria-hidden='true'>" +
        "  <div class='modal-dialog modal-dialog-center'>" +
        "    <div class='modal-content'>" +
        "        <div class='modal-header'>" +
        "          <button type='button' class='close' data-dismiss='modal' aria-hidden='true'>" +
        "            &times;" +
        "          </button>" +
        "          <blockquote>" +
        "              <h4 class='modal-title' id='myModalLabel'>{{video.title}}</h4>" +
        "          </blockquote>" +
        "        </div>" +
        "        <div class='modal-body'>" +
        "          <p class='text-primary text-center'>{{title}}</p>" +
        "          <video id='tfVideo' data-youtube-id={{video.ytId}} height={{video.height}} width={{video.width}} title={{video.title}} preload='none'></video>" +
        "        </div>" +
        "        <div class='modal-footer'>" +
        "        </div>" +
        "    </div><!-- /.modal-content -->" +
        "  </div><!-- /.modal-dialog -->" +
        "</div><!-- /.modal -->"
      "</div>";
    
      return {
        restrct: 'E',
        scope: {
          video : "=",
        },
        template: htmlTemplate
      };
    });
    

    工厂:

    myApp.factory('trailers',function(){
      var trailers = [
          {
            ytId: "6kw1UVovByw",
            imgSrc:"http://img.youtube.com/vi/6kw1UVovByw/0.jpg",
            width:"320",
            height:"300",
            title:"My Custom Title 1",
            lang: "English",
            relDate: "2013/17/11",
            rating: "3.5"
          },
          {
            ytId: "uWgDVz4NEO4",
            imgSrc:"http://img.youtube.com/vi/uWgDVz4NEO4/0.jpg",
            width:"320",
            height:"300",
            title:"My Custom Title 2",
            lang: "Hindi",
            relDate: "2013/17/11",
            rating: "3.5"
          }];
      return trailers;
    });
    

    在我的HTML中

    <div trailer-list on-click="openVideo(video)" video="video" ng-repeat="video in videos | filter:languageFilter">
    </div>
    
    <div modal-layer video='selectedVideo'></div>
    

1 个答案:

答案 0 :(得分:0)

您的控制器已经有$ scope。$ apply();

尝试将其替换为

$scope.openVideo = function(video){


  $scope.$apply(function(){
      $scope.selectedVideo = video;
      sublime.ready(function(){ // jquery based sublime video api
      console.log("Video Selected = " + JSON.stringify(video));
      $("#tfModal").modal({}); // invoking bootstrap modal
      $('#tfModal').on('shown.bs.modal', function (e) {
        console.log('preparing...');
        sublime.prepare('tfVideo', function(player) {
          player.play();
      });
    });
  });

  $('#tfModal').on('hidden.bs.modal', function (e) {
      console.log('un preparing...');
      sublime.unprepare('tfVideo');
    })


  }

替换你的代码IN $ apply function。