-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
model change handler is not executed after sorting or nesting items #13
Comments
I'm having the same problem. Did you end up fixing it yourself? |
Hello @malevolm I tried to figure out how did I solve it , but I could not remember , but the version is working fine for me. Please note that I've added a handle to the dragable element you may need to include this class in your CSS file .dd3-item > button { /**
* Angular nestable 0.0.1
* Copyright (c) 2014 Kamil Pekala
* https://github.com/kamilkp/ng-nestable
*/
/**
* Sample output HTML
<div class="dd">
<ol class="dd-list">
<li class="dd-item" data-id="1">
<!-- item element -->
</li>
<li class="dd-item" data-id="2">
<!-- item element -->
</li>
<li class="dd-item" data-id="3">
<!-- item element -->
<ol class="dd-list">
<li class="dd-item" data-id="4">
<!-- item element -->
</li>
<li class="dd-item" data-id="5">
<!-- item element -->
</li>
</ol>
</li>
</ol>
</div>
*/
/**
* Sample model object
[
{
item: {},
children: []
},
{
item: {},
children: [
{
item: {},
children: []
}
]
},
{
item: {},
children: []
}
]
*/
;(function(window, document, angular, undefined){
angular.module('ng-nestable', [])
.provider('$nestable', function(){
var modelName = '$item';
var defaultOptions = {};
this.$get = function(){
return {
modelName: modelName,
defaultOptions: defaultOptions
};
};
/**
* Method to set model variable for nestable elements
* @param {[string]} value
*/
this.modelName = function(value){
modelName = value;
};
/**
* Method to set default nestable options
* @param {[object]} value
* You can change the follow options:
maxDepth : number of levels an item can be nested (default 5)
group : group ID to allow dragging between lists (default 0)
listNodeName : The HTML element to create for lists (default 'ol')
itemNodeName : The HTML element to create for list items (default 'li')
rootClass : The class of the root element .nestable() was used on (default 'dd')
listClass : The class of all list elements (default 'dd-list')
itemClass : The class of all list item elements (default 'dd-item')
dragClass : The class applied to the list element that is being dragged (default 'dd-dragel')
handleClass : The class of the content element inside each list item (default 'dd-handle')
collapsedClass : The class applied to lists that have been collapsed (default 'dd-collapsed')
placeClass : The class of the placeholder element (default 'dd-placeholder')
emptyClass : The class used for empty list placeholder elements (default 'dd-empty')
expandBtnHTML : The HTML text used to generate a list item expand button (default '<button data-action="expand">Expand></button>')
collapseBtnHTML : The HTML text used to generate a list item collapse button (default '<button data-action="collapse">Collapse</button>')
*/
this.defaultOptions = function(value){
defaultOptions = value;
};
})
.directive('ngNestable', ['$compile', '$nestable', function($compile, $nestable){
return {
restrict: 'A',
require: 'ngModel',
compile: function(element){
var itemTemplate = element.html();
element.empty();
return function($scope, $element, $attrs, $ngModel){
var options = $.extend(
{ maxDepth: 2 },
$nestable.defaultOptions,
$scope.$eval($attrs.ngNestable)
);
$scope.$watchCollection(function(){
return $ngModel.$modelValue;
}, function(model){
if(model){
/**
* we are running the formatters here instead of watching on $viewValue because our model is an Array
* and angularjs ngModel watcher watches for "shallow" changes and otherwise the possible formatters wouldn't
* get executed
*/
model = runFormatters(model, $ngModel);
// TODO: optimize as rebuilding is not necessary here
var root = buildNestableHtml(model, itemTemplate);
$element.empty().append(root);
$compile(root)($scope);
root.nestable(options);
root.on('change', function(){
$ngModel.$setViewValue(root.nestable('serialize'));
$scope && $scope.$root && $scope.$root.$$phase || $scope.$apply();
});
}
});
};
},
controller: angular.noop
};
function buildNestableHtml(model, tpl){
var root = $('<div class="dd"></div>');
var rootList = $('<ol class="dd-list"></ol>').appendTo(root);
model.forEach(function f(item){
var list = Array.prototype.slice.call(arguments).slice(-1)[0];
if(!(list instanceof $)) list = rootList;
var listItem = $('<li class="dd-item dd3-item"></li>');
var listHandle = $('<div class="dd-handle dd3-handle">Drag</div>')
var listElement = $('<div ng-nestable-item class="dd3-content"></div>');
listHandle.appendTo(listItem);
listElement.append(tpl).appendTo(listItem);
list.append(listItem);
listItem.data('item', item.item);
if(isArray(item.children) && item.children.length > 0){
var subRoot = $('<ol class="dd-list"></ol>').appendTo(listItem);
item.children.forEach(function(item){
f.apply(this, Array.prototype.slice.call(arguments).concat([subRoot]));
});
}
});
return root;
}
function isArray(arr){
return Object.prototype.toString.call(arr) === '[object Array]';
}
function runFormatters(value, ctrl){
var formatters = ctrl.$formatters,
idx = formatters.length;
ctrl.$modelValue = value;
while(idx--) {
value = formatters[idx](value);
}
return value;
}
}])
.directive('ngNestableItem', ['$nestable', function($nestable){
return {
scope: true,
require: '^ngNestable',
link: function($scope, $element){
$scope[$nestable.modelName] = $element.parent().data('item');
}
};
}]);
})(window, document, window.angular); |
I just changed $watchCollection to $watch and passed the third parameter as true. |
I tried both of ways. but nothing changed :( |
You will notice above |
Is there an official solution? |
Hello
after nesting or sorting items by dragging them ,I'm not able to add more items to ng-nestable,
i.e after this handler get executed , the model will never change , so the html is not rebuilt
root.on('change', function () {
$ngModel.$setViewValue(root.nestable('serialize'));
$scope && $scope.$root && $scope.$root.$$phase || $scope.$apply();
}
Thanks
The text was updated successfully, but these errors were encountered: