2014-05-14 21 views
5

मेरे पास क्लिक होने पर विस्तार और अनुबंध divs है। चिनाई पुस्तकालय ने पेज को शुरू करने के लिए बहुत अच्छा काम किया है। जिस समस्या का मैं अनुभव कर रहा हूं वह यह है कि चिनाई से पूर्ण स्थिति और नीचे दिए गए निर्देश के साथ, जब divs का विस्तार होता है तो वे नीचे divs के साथ ओवरलैप करते हैं। मुझे विस्तार से निपटने के लिए विस्तारित div आगे बढ़ने के नीचे divs होना चाहिए।गतिशील रूप से बदलती ऊंचाइयों के लिए कोणीय जेएस चिनाई

मेरे स्रोत हैं: http://masonry.desandro.com/

और

https://github.com/passy/angular-masonry/blob/master/src/angular-masonry.js

/*! 
* angular-masonry <%= pkg.version %> 
* Pascal Hartig, weluse GmbH, http://weluse.de/ 
* License: MIT 
*/ 
(function() { 
    'use strict'; 

angular.module('wu.masonry', []) 
.controller('MasonryCtrl', function controller($scope, $element, $timeout) { 
    var bricks = {}; 
    var schedule = []; 
    var destroyed = false; 
    var self = this; 
    var timeout = null; 

    this.preserveOrder = false; 
    this.loadImages = true; 

    this.scheduleMasonryOnce = function scheduleMasonryOnce() { 
    var args = arguments; 
    var found = schedule.filter(function filterFn(item) { 
     return item[0] === args[0]; 
    }).length > 0; 

    if (!found) { 
     this.scheduleMasonry.apply(null, arguments); 
    } 
    }; 

    // Make sure it's only executed once within a reasonable time-frame in 
    // case multiple elements are removed or added at once. 
    this.scheduleMasonry = function scheduleMasonry() { 
    if (timeout) { 
     $timeout.cancel(timeout); 
    } 

    schedule.push([].slice.call(arguments)); 

    timeout = $timeout(function runMasonry() { 
     if (destroyed) { 
     return; 
     } 
     schedule.forEach(function scheduleForEach(args) { 
     $element.masonry.apply($element, args); 
     }); 
     schedule = []; 
    }, 30); 
    }; 

    function defaultLoaded($element) { 
    $element.addClass('loaded'); 
    } 

    this.appendBrick = function appendBrick(element, id) { 
    if (destroyed) { 
     return; 
    } 

    function _append() { 
     if (Object.keys(bricks).length === 0) { 
     $element.masonry('resize'); 
     } 
     if (bricks[id] === undefined) { 
     // Keep track of added elements. 
     bricks[id] = true; 
     defaultLoaded(element); 
     $element.masonry('appended', element, true); 
     } 
    } 

    function _layout() { 
     // I wanted to make this dynamic but ran into huuuge memory leaks 
     // that I couldn't fix. If you know how to dynamically add a 
     // callback so one could say <masonry loaded="callback($element)"> 
     // please submit a pull request! 
     self.scheduleMasonryOnce('layout'); 
    } 

    if (!self.loadImages){ 
     _append(); 
     _layout(); 
    } else if (self.preserveOrder) { 
     _append(); 
     element.imagesLoaded(_layout); 
    } else { 
     element.imagesLoaded(function imagesLoaded() { 
     _append(); 
     _layout(); 
     }); 
    } 
    }; 

    this.removeBrick = function removeBrick(id, element) { 
    if (destroyed) { 
     return; 
    } 

    delete bricks[id]; 
    $element.masonry('remove', element); 
    this.scheduleMasonryOnce('layout'); 
    }; 

    this.destroy = function destroy() { 
    destroyed = true; 

    if ($element.data('masonry')) { 
     // Gently uninitialize if still present 
     $element.masonry('destroy'); 
    } 
    $scope.$emit('masonry.destroyed'); 

    bricks = []; 
    }; 

    this.reload = function reload() { 
    $element.masonry(); 
    $scope.$emit('masonry.reloaded'); 
    }; 


}).directive('masonry', function masonryDirective() { 
    return { 
    restrict: 'AE', 
    controller: 'MasonryCtrl', 
    link: { 
     pre: function preLink(scope, element, attrs, ctrl) { 
     var attrOptions = scope.$eval(attrs.masonry || attrs.masonryOptions); 
     var options = angular.extend({ 
      itemSelector: attrs.itemSelector || '.masonry-brick', 
      columnWidth: parseInt(attrs.columnWidth, 10) || attrs.columnWidth 
     }, attrOptions || {}); 
     element.masonry(options); 
     var loadImages = scope.$eval(attrs.loadImages); 
     ctrl.loadImages = loadImages !== false; 
     var preserveOrder = scope.$eval(attrs.preserveOrder); 
     ctrl.preserveOrder = (preserveOrder !== false && attrs.preserveOrder !== undefined); 

     scope.$emit('masonry.created', element); 
     scope.$on('$destroy', ctrl.destroy); 
     } 
    } 
    }; 
}).directive('masonryBrick', function masonryBrickDirective() { 
    return { 
    restrict: 'AC', 
    require: '^masonry', 
    scope: true, 
    link: { 
     pre: function preLink(scope, element, attrs, ctrl) { 
     var id = scope.$id, index; 

     ctrl.appendBrick(element, id); 
     element.on('$destroy', function() { 
      ctrl.removeBrick(id, element); 
     }); 

     scope.$on('masonry.reload', function() { 
      ctrl.scheduleMasonryOnce('reloadItems'); 
      ctrl.scheduleMasonryOnce('layout'); 
     }); 

     scope.$watch('$index', function() { 
      if (index !== undefined && index !== scope.$index) { 
      ctrl.scheduleMasonryOnce('reloadItems'); 
      ctrl.scheduleMasonryOnce('layout'); 
      } 
      index = scope.$index; 
     }); 
     } 
    } 
    }; 
}); 
}()); 
+0

मुझे लगता है कि समाधान इन घटनाओं में से किसी एक के बाद फिर से चिनाई चलाने के लिए है, लेकिन मैं यह समझने में सक्षम नहीं हूं कि एंगुलर नियंत्रक के अंदर से ऐसा करने के लिए मैं इसे कैसे कर सकता हूं। मैंने एक उपहार दिया है इस सवाल के लिए। – Guy

+1

कृपया –

+0

समस्या का प्रदर्शन करने वाला एक साधारण प्लंकर बनाएं या आप केवल एक सरल निर्देश लिख सकते हैं: http://plnkr.co/edit/UyRS0clrCwDpSrYgBsXS?p=preview – SoluableNonagon

उत्तर

1

कई गैर कोणीय पुस्तकालयों के साथ की तरह, यह प्रतीत होता है इस सवाल का जवाब एक कोणीय निर्देश में पुस्तकालय लपेटकर में निहित है।

मैं इसे बाहर की कोशिश की नहीं है, लेकिन ऐसा लगता है कि क्या this person did

+1

हां, ओपी ने उस 2 पुस्तकालयों में से एक के रूप में लिंक को शामिल किया है उपयोग कर रहा है। जिस समस्या को हम हल करने का प्रयास कर रहे हैं वह यह है कि आप अपने नियंत्रक के भीतर से चिनाई फ़ंक्शन को फिर से "रीफ्रेश" कहने के लिए कहें क्योंकि आपने पृष्ठ पर मौजूद घटकों के आकार में परिवर्तन किए हैं। – Guy

0

आप उपयोग कर सकते हैं के कोणीय $ फेंकना, $ प्रसारण, और $ कार्यक्षमता पर।

अपने masonry निर्देश लिंक समारोह के अंदर:

scope.$on('$resizeMasonry', ctrl.scheduleMasonryOnce('layout'));

अपने masonryBrick निर्देश लिंक समारोह या किसी अन्य चाइल्ड तत्व के अंदर:

scope.$emit('$resizeMasonry');

उपयोग $ एक घटना भेजने की फेंकना स्कोप पेड़ और स्कोप पेड़ के नीचे एक घटना भेजने के लिए $ प्रसारण।

+0

धन्यवाद ट्रैविस। कल्पना करें कि आपने एक परियोजना में चिनाई और कोणीय-चिनाई दोनों को शामिल किया था और एक पृष्ठ पर आपके नियंत्रक में आपने एक क्लिक ईवेंट के माध्यम से एक तत्व जोड़ा था। यह तत्व अब एक और तत्व ओवरलैप करता है। पृष्ठ के नियंत्रक के भीतर से अब आप "चिनाई रीफ्रेश/पुनः लोड" कैसे कॉल करेंगे? – Guy

+0

@Guy, यह उस पर निर्भर करेगा जहां नियंत्रक का दायरा 'MasonryCtrl' के संबंध में है। यदि यह एक बच्चा गुंजाइश है तो आप $ माता-पिता के दायरे में उत्सर्जित करना चाहेंगे। यदि यह एक मूल दायरा $ प्रसारण का उपयोग करता है। अंतिम उपाय के रूप में $ $ रूटस्कोप। $ प्रसारण' सभी क्षेत्रों में उलझ जाएगा। – Travis

संबंधित मुद्दे