如果我在数组中推送其他小部件,Packery 无法在 AngularJS 上工作

Packery not working on AngularJS if i push additional widgets in my array

我现在搜索了相当多的时间,但仍然找不到解决我的问题的方法。 我对 Packery 一无所知,但我发现这段代码运行良好,可以做我想做的事情。

directive('workspace', ['$rootScope', function($rootScope) {
 return {
constrain: 'A',
link: function(scope, element, attrs) {
  element.ready(function() {
    var packery = new Packery(element[0], {
      rowHeight: '.module-sizer',
      itemSelector: '.module',
      columnWidth: '.module-sizer'
    });
    angular.forEach(packery.getItemElements(), function(item) {
      var draggable = new Draggabilly(item);
      packery.bindDraggabillyEvents(draggable);
    });
    packery.layout();
  });
} }; }]).

因此,当我有一组小部件时,我没有添加或删除元素,而是简单地使用 ng-show hide/show 它们,它工作得很好。现在我不再想使用 ng-show,而是从一个初始的空数组中添加和删除我的小部件

.controller('WidgetCtrl', ['$scope', function ($scope) {
$scope.counter = 0;
$scope.current = 0;
$scope.widgets = [];


$scope.addWidget = function(name){
  var widgets = {
    widget1: {name: 'widget1', id: ''},
    widget2: {name: 'widget2', data: {dataVariable: 'some data'}, id:''}
  };
  var widget = widgets[name];

 if (widget) {
    $scope.widgets.push(widget);
    $scope.widgets[$scope.current].id = $scope.widgets.length-1;
    console.log('index of the last widget added: ' + $scope.widgets[$scope.current].id);
    $scope.current++;}

所以唯一可以拖动的小部件是那些最初在数组中的小部件。我在页面加载后添加的任何小部件都将不起作用。我是 angular 的新手,我正在阅读 $scope.apply 并重新编译一个指令,但我不确定它是否与我的问题有关

<div class="module-container" workspace>                                
                            <div class="module-sizer"></div>
                            <div class="gutter-sizer"></div>
            <div class="module" ng-repeat='widget in widgets'>
                <div dynamic-widget='widget.name' data='widget.data'> </div>
            </div>
      </div>

这里的问题是关于 packery 将事件绑定到网格项目以执行布局和制作它们的事实 'draggable',这里是负责的片段:

angular.forEach(packery.getItemElements(), function(item) {
      var draggable = new Draggabilly(item);
      packery.bindDraggabillyEvents(draggable);
});

因此,您的指令设置方式目前正在发生的事情是,当包含指令的模板最初加载时,它会选择任何匹配的项目 .module 并使用上述代码初始化 packery & draggabilly pckry.layout();,从那时起,您的应用程序根本无法知道小部件的数量已经增加。

要确保它们在添加时被初始化,您可以做的是将范围传递到指令中,如下所示:

constrain: 'A',
scope: true,
link: // ...

然后您需要将 $scope.$watchCollection 添加到数组 widgets 中,如下所示:

$scope.$watchCollection('widgets', function() {
            // Call packery and draggabilly on elems here
});

我想你会想要将初始化 packery 的逻辑移动到一个单独的函数中以更好地分离代码,但请注意 $watchCollection 无论如何都会在指令第一次运行时触发,所以所有的逻辑可能就在里面。

最后要注意的是,您可能需要提前调用 pckry.destroy(); 以确保获得所需的结果。不幸的是,我没有足够的时间来举个例子,所以这真的只是一个思想实验,但我希望它能有所帮助!