jQuery插件与Angularjs不兼容
我在我的项目中使用了jQuery滑块 ,我使用angular加载图像。 我目前的观点是这样的;
控制器;
blogApp.controller("HomeController", ['$scope', '$resource', function ($scope, $resource) { var basePath = '/api/', FrontGallery = $resource(basePath + 'gallery?culture=en-US'), $scope.gallery = FrontGallery.query(); }]);
和jQuery滑块代码(使它成为一个滑块。我正在使用这个插件http://archive.slidesjs.com/ )
$(document).ready(function () { $('#slides').slides({ preload: true, preloadImage: '/content/images/theme/loading.gif', play: 5000, pause: 2500, hoverPause: true }); });
什么时候,我尝试这个代码,我的所有图像都从数据库加载(通过firebug调试) 但jQuery滑块没有应用动画或滑动效果到它
当我删除data-ng-repeat="image in gallery
中的data-ng-repeat="image in gallery
并使用一些静态内容即图像时,我得到了滑动效果。
这有什么问题。 我认为Angular正在操纵我的DOM。 这就是为什么我每次放置时都会遇到这个问题,即在我的滑块上使用一些角度属性。
注意:我对jQuery新闻有同样的问题,即jQuery InnerFade
插件http://medienfreunde.com/lab/innerfade/
以下是innerFade
的使用方法;
Hot News
和控制器;
var HotNews = $resource(basePath + 'article/hotnews?culture=en-US'); $scope.news = HotNews.query();
我该如何解决这些问题?
更新2:这是我的路线;
// declare a module var blogApp = angular .module('blogApp', ['ngResource', 'ngSanitize']) .config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) { //$locationProvider.html5Mode(true); //configure the routes $routeProvider .when('/', { // list the home page templateUrl: "tmpl/home.html", controller: "HomeController" }) .when('/article/:id', { // access custom param foo: "hello world", // list the home page templateUrl: "tmpl/article.html", controller: "ArticleController" }) .when('/404', { template: '404 Not Found!
' }) .otherwise({ redirectTo: '/404' }); }]);
解决方案#1:临时,(正如@Jason Goemaat回答的)对我有用 。 所以,这就是我所做的。 我没有创建任何directive
但直接我将$timeout
注入我的控制器,然后我做了以下操作;
$timeout(function () { jQuery('#news').innerfade({ animationtype: 'slide', speed: 750, timeout: 2000, type: 'random', containerheight: '1em' }); jQuery('#slides').slides({ preload: true, preloadImage: 'image/theme/loading.gif', play: 5000, pause: 2500, hoverPause: true }); }, 100);
它确实适用于Slider
和InnerFade
Angular IS操纵你的dom,ng-repeat指令在有一个可以使用的列表时创建元素。 因此,你需要在角度完成之后调用.slides
创建元素,因为该插件正在改变DOM本身。
这是一个指令,您可以使用它来根据数组长度> 0时调用元素上的$.slides
。它显示使用额外的属性,如’start’来修改对幻灯片的调用。 在这里,它检查$ scope上的一个名为’images’的数组,并在链接阶段调用$timeout()
,以便在创建DOM时完成角度调用.slidesjs()
。 我不知道你使用了什么插件,所以我发现了一个名为’ slidejs ,看起来很相似。 ‘这是一个吸烟者: http ://plnkr.co/edit/4qdUctYMIpd8WqEg0OiO?p=preview
HTML:
指示:
app.directive('mySlides', function() { var directive = { restrict: 'A', link: function(scope, element, attrs, ctrl) { scope.$watch(attrs.mySlides, function(value) { setTimeout(function() { // only if we have images since .slidesjs() can't // be called more than once if (value.length > 0) { $(element[0]).slidesjs({ preload: true, preloadImage: '/content/images/theme/loading.gif', play: attrs.play || 5000, pause: attrs.pause || 2500, start: attrs.start || 1, hoverPause: attrs.hoverPause || true, navigation: { active: true, effect: "slide" } }); } }, 1); }); } }; return directive; });
需要注意的一点是,它仍然只能被调用一次,因此如果您的图像列表得到更新,它将无法工作。 为此,您可以在指令中创建内容……
$(document).ready(function () {
在角度已将内容加载到页面上之前触发。 只有在角度加载内容后才能激活jQuery滑块脚本。 这里的部分问题是angular不提供$digest
的回调,所以你没有要监听的事件。
内容加载 – >事件回调 – > ui构建,虽然在jQuery和标准的javascript思维中很常见,但它不是角度心态的一部分。 幸运的角度有一个非常强大的方法来处理这个问题。
您需要的是将jQuery幻灯片脚本转换为角度指令 。 然后它将成为角度处理空间的一部分并被实例化为角度摘要周期的一部分。
就像是
祝好运!
使用innerfade的快乐示例时间(我还没有测试过,会尽快做到)。 首先,您的应用程序必须声明角度模块(如果尚未声明)。 ng-app="myModule"
。 http://docs.angularjs.org/api/angular.module
(确保您的控制器也已连接!)
现在您可以在该模块上声明一个指令。 哪个超酷。
angular.module('myModule').directive("innerFade", function () { var res = { restrict : 'C', link : function (scope, element, attrs) { scope.$watch(attrs.innerFade, function(){ element.innerfade({ speed: 'slow', timeout: 1000, type: 'sequence', containerheight: '1.5em' }); }); } }; return res; });
这种方式非常简单。 $watch
函数将监视包含数据的范围部分。 当更改(包括初始化)时,它将使用指令触发element
上的innerfade
jQuery函数。 我们也将’C’传递给restrict参数,所以这个自定义指令将是一个只有类的指令(我注意到你似乎喜欢这样)。
- {{fadeItem}}
现在你所要做的就是将数据绑定到控制器中的$scope.innerData
(以任何你喜欢的方式绑定它,包括ajax),它就可以了。 您甚至可以更改$scope.innerData
上的数据,它将使用完整的jQuery荣耀进行更新。
一些想法
1)我的猜测是你的主应用页面有一些顺序错误。 在 angularjs 之后你有jQuery包含吗? 我假设您正在使用ng-repeat指令?
2)将$更改为jQuery
3)将document.ready脚本放在主页面中……也考虑将其替换为
window.onload=function(){}
如果你能显示主页面和视图的代码,我相信我可以调试。
向#slides添加指令
app.directive("slideDirective", function () { return function (scope, element, attrs) { // Dom element.slides({ preload: true, preloadImage: '/content/images/theme/loading.gif', play: 5000, pause: 2500, hoverPause: true }); } }
正如所说:“jQuery滑块脚本只应在angular加载内容后才能激活”所以你可以等到它加载之后,然后你的jQuery代码就会开始运行。
$(document).ready(function () { setTimeout(function(){ $('#slides').slides({ preload: true, preloadImage: '/content/images/theme/loading.gif', play: 5000, pause: 2500, hoverPause: true }); }, 10); });