Gridster jQuery plugin on AngularJS ng-repeat content going bad

匿名 (未验证) 提交于 2019-12-03 02:50:02

问题:

I'm trying to integrate Gridster with AngularJS, but without too much success yet.

Reading the documentation on Angular UI's ui-jq directive, I get the impression that this (check fiddle) should work. But when I look a bit further with Chrome's debugger, it turns out that on this line, it doesn't find any children at all.

I suspect that somewhere in the ng-repeat directive, AngularJS decides to rip out the part that will be repeated, and I see why, but that doesn't solve my problem. I'd welcome any clue that would help me to get a little further.

Update 1

I started turning it into a directive, hoping that would improve things. However, the nested ng-repeat is also getting in the way in case of a homegrown directive. I tried postponing hooking up the jQuery plugin as long as I could ($evalAsync) and alike, and eventually ended up using a $timeout. That's the only way in which I could get it working.

Update 2

I think the original approach would have never given me what I needed. So implemented a custom directive. See my answer below.

回答1:

I eventually ended up writing my own directives for it. I needed to be sure that every change to the underlying data would be seen by gridster, but at the same time, I didn't want to write my own monitoring on the data model and replace everything you normally do within gridster with a directive that hides all of that. (It would involve implementing most of ng-repeat within the directive itself.)

This is what I have (and assume "foo" to be the name of my module):

foo.directive "gridster", () -> {   restrict: "E"   template: '<div class="gridster"><div ng-transclude/></div>'   transclude: true   replace: true   controller: () ->     gr = null     return {       init: (elem) ->         ul = elem.find("ul")         gr = ul.gridster().data('gridster')         return       addItem: (elm) ->         gr.add_widget elm         return       removeItem: (elm) ->         gr.remove_widget elm         return     }   link: (scope, elem, attrs, controller) ->     controller.init elem }  foo.directive "gridsterItem", () -> {   restrict: "A"   require: "^gridster"   link: (scope, elm, attrs, controller) ->     controller.addItem elm     elm.bind "$destroy", () ->       controller.removeItem elm       return } 

With this, I can have a gridster generated view, by adding this:

<gridster>   <ul>     <li ... ng-repeat="item in ..." gridster-item>       <!-- Have something here for displaying that item. -->       <!-- In my case, I'm switching here based on some item properties. -->     </li>   </ul> </gridster>

Whenever items are added to or removed from the collection observed by the ng-repeat directive, they will be automatically added and removed from gridster controlled view.

EDIT

Here is a plunk demonstrating a slightly modified version of this directive:

angular.module('ngGridster', []);  angular.module('ngGridster').directive('gridster', [     function () {         return {             restrict: 'E',             template: '<div class="gridster"><div ng-transclude/></div>',             transclude: true,             replace: true,             controller: function () {                 gr = null;                 return {                     init: function (elem, options) {                         ul = $(elem);                         gr = ul.gridster(angular.extend({                           widget_selector: 'gridster-item'                         }, options)).data('gridster');                     },                     addItem: function (elm)  {                         gr.add_widget(elm);                     },                     removeItem: function (elm) {                         gr.remove_widget(elm);                     }                 };             },             link: function (scope, elem, attrs, controller) {               var options = scope.$eval(attrs.options);               controller.init(elem, options);             }         };     } ]);  angular.module('ngGridster').directive('gridsterItem', [     function () {         return {             restrict: 'EA',             require: '^gridster',             link: function (scope, elm, attrs, controller) {                 controller.addItem(elm);                 elm.bind('$destroy', function () {                     controller.removeItem(elm);                 });             }         };     } ]);


回答2:

If you want you can try and roll your own wrapper for gridster. I spent most of the night last night and it was a little glitchy. The way gridster handles serialization isn't straightforward, etc. Anyway I stumbled on this project and it works really well.

https://github.com/ManifestWebDesign/angular-gridster

I couldn't find an online demo so I made a plunk of it:

http://plnkr.co/edit/r5cSY1USjtr2bSs7rvlC?p=preview



回答3:

This will be fixed in the next release of

https://github.com/angular-ui/angular-ui/pull/347

The new deferred attribute will take care of the problem as soon as I can figure out why the stupid unit tests won't pass.



回答4:

There's also Angular Gridster.

Came across it and this question while researching Gridster implementation in Angular.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!