AngularJS - 在使用滑块标记GTSs JSON对象之后无法初始化jQuery Slider

时间:2016-12-17 14:46:16

标签: angularjs ajax asynchronous watch

我试图将Slick Slider Carousel初始化为 AngularJS App

我在一定程度上使用了我创建的名为slickSlider的指令(下面的代码)。问题是它只有在我将滑块的标记直接添加到html模板时才有效,而不是如果我从使用promises / deferred的外部服务获取标记时仅获取数据的标记。必需的。

当我在chrome sources面板上放置断点时,我发现在Controller从服务获取数据之前正在运行slickSlider指令代码,因此指令代码无效。

我在下面的snippit中缩小了我的应用版本中的问题。

  • 如何在指令后初始化滑块 service已获取控制器的数据并已通过 观点?
  • 我应该尝试以其他方式初始化滑块吗?



var app = angular.module('app', ['ngSanitize']);

app.controller('postsController', ['postsService', function (postsService) {
  var postsCtrl = this;
  postsCtrl.test = 'this is an expression from the controller'
  var promise = postsService.getPost(1);
    
    promise.then(function (data)
    {
        postsCtrl.data = data.data;
        
        // I can't access the API on SO so am replicating what I would get from it here.
        postsCtrl.slider = '<div class=\"slick-slider\">\n \n <div>Service Slide 1<\/div>\n \n <div>Service Slide 2<\/div>\n \n <div>Service Slide 3<\/div>\n \n <\/div>';
    });
}]);

app.service("postsService", function ($http, $q) {
    function getPost(postsId) {
      var deferred = $q.defer()
      var url = 'https://jsonplaceholder.typicode.com/albums/' + postsId;
      $http({
        method: 'GET', // GET OPTIONS
        cache: true,
        url: url,
        headers: {  
           'Content-Type': 'application/json;charset=UTF-8'
        }
      }).
      then(function(response) {
        //your code when success
        deferred.resolve(response);
      }, function(response) {
        //your code when fails
        deferred.reject(response);
      });
      return deferred.promise;
    }
    this.getPost = getPost;
});

app.directive('slickSlider',function(){
 return {
   restrict: 'C',
    link: function(scope, elem, attrs) {
      $(elem).slick({
            // settings
      }); 
    }
  }
});
&#13;
body {
  font-family: sans-serif;
  font-size: 14px;  
}
h1 {
  font-size: 15px;
  margin: 20px 0 2px;
}
&#13;
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<script src="https://code.angularjs.org/1.5.9/angular-sanitize.min.js"></script>
<script type="text/javascript" src="//cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
<body ng-app="app" ng-controller="postsController as postsCtrl">
	Controller is working... &nbsp; <i>{{postsCtrl.test}}</i> <br />
  	Service is working...  &nbsp; <i>{{postsCtrl.data.title}}</i>
	<h1>Slider Carousel markup from simple HTML</h1>
	<div class="slick-slider">
		<div>HTML Slide 1</div>
		<div>HTML Slide 2</div>
		<div>HTML Slide 3</div>
	</div>
	<h1>Slider Carousel markup from expression supplied by Service</h1>
    <div ng-bind-html="postsCtrl.slider"></div>     
</body>
&#13;
&#13;
&#13;

更新

我尝试在我的指令中使用$timeout,但它没有用!

app.directive('slickSlider',function($timeout){
 return {
   restrict: 'C',
    link: function(scope, elem, attrs) {
      $timeout(function () {
        $(elem).slick({
            // settings
        }); 
      });
    }
  }
});

1 个答案:

答案 0 :(得分:1)

您需要在postsCtrl.slider值更改后重新编译元素。

&#13;
&#13;
var app = angular.module('app', ['ngSanitize']);

app.controller('postsController', ['postsService',
  function(postsService) {
    var postsCtrl = this;
    postsCtrl.test = 'this is an expression from the controller'
    var promise = postsService.getPost(1);

    promise.then(function(data) {
      postsCtrl.data = data.data;

      // I can't access the API on SO so am replicating what I would get from it here.
      postsCtrl.slider = '<div class=\"slick-slider\">\n \n <div>Service Slide 1<\/div>\n \n <div>Service Slide 2<\/div>\n \n <div>Service Slide 3<\/div>\n \n <\/div>';
    });
  }
]);

app.service("postsService", function($http, $q) {
  function getPost(postsId) {
    var deferred = $q.defer()
    var url = 'https://jsonplaceholder.typicode.com/albums/' + postsId;
    $http({
      method: 'GET', // GET OPTIONS
      cache: true,
      url: url,
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
      }
    }).
    then(function(response) {
      //your code when success
      deferred.resolve(response);
    }, function(response) {
      //your code when fails
      deferred.reject(response);
    });
    return deferred.promise;
  }
  this.getPost = getPost;
});

app.directive('slickSliderContent', function($compile) {
  return {
    restrict: 'A',
    replace: true,
    link: function(scope, elem, attrs) {
      scope.$watch(attrs.slickSliderContent, function(html) {
          elem[0].innerHTML = html;
          $compile(elem.contents())(scope);
      });
    }
  }
});

app.directive('slickSlider', function() {
  return {
    restrict: 'C',
    link: function(scope, elem, attrs) {
      $(elem).slick({
        // settings
      });
    }
  }
});
&#13;
body {
  font-family: sans-serif;
  font-size: 14px;
}
h1 {
  font-size: 15px;
  margin: 20px 0 2px;
}
&#13;
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<script src="https://code.angularjs.org/1.5.9/angular-sanitize.min.js"></script>
<script type="text/javascript" src="//cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>

<body ng-app="app" ng-controller="postsController as postsCtrl">

  <div class="slick-slider" slick-slider-content="postsCtrl.slider"></div>
</body>
&#13;
&#13;
&#13;