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

Posted

技术标签:

【中文标题】如果我在数组中推送其他小部件,Packery 无法在 AngularJS 上运行【英文标题】:Packery not working on AngularJS if i push additional widgets in my array 【发布时间】:2015-08-31 09:46:21 【问题描述】:

我现在搜索了相当长的时间,但仍然找不到解决问题的方法。 我对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 隐藏/显示它们。现在我不再想使用 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>

【问题讨论】:

【参考方案1】:

这里的问题是因为 packery 将事件绑定到网格项目以执行布局并使它们“可拖动”,这是负责该问题的 sn-p:

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

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

为了确保它们在添加时被初始化,您可以做的是将作用域传递给指令,如下所示:

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

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

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

我想您可能希望将初始化打包程序的逻辑移动到一个单独的函数中以更好地分离代码,但请注意$watchCollection 将在指令第一次运行时触发,因此所有逻辑都可能在里面在那里。

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

【讨论】:

以上是关于如果我在数组中推送其他小部件,Packery 无法在 AngularJS 上运行的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:单击 TextField 时,推送的 LoginScreen 小部件正在重建 UI

其他非 qt 窗口顶部的 Qt 小部件

摇动动画“滑入”其他小部件 android

所有控制器上的快速播放器小部件

Metafizzy Packery 组件中的动态调整大小效果

如何在BOOT_COMPLETED更新第三方小部件?