delete an object stored in several ArrayCollections - actionscript

I have several arraycollections (I don't know their number in advance) which contain one same object (among others).
var obj:MyObject = new MyObject();
var arc1:ArrayCollection = new ArrayCollection();
arc1.addItem(obj)
// same operation for my x arraycollections
Is it possible to delete my object "obj" in the first arraycollection and automatically delete it in all other arraycollections too without deleting it in each arraycollection one by one?

Assuming that all your array collections share a common source, I would create ListCollectionViews instead of ArrayCollections and have them all point to a single ArrayCollection, i.e:
var masterCollection:ArrayCollection = new ArrayCollection();
for (var i:uint = 0; i < N; i++)
{
slaveCollections[i] = new ListCollectionView(masterCollection);
}
Whenever you add or remove an item from any slaveCollection it will be added/removed from the master and all your other lists will be updated via the CollectionEvent.

Assuming that all your array collections do NOT share a common source, I would add a collection event listener to each collection to handle your requirement:
for (var i:uint = 0; i < N; i++)
{
slaveCollections[i] = new ArrayCollection();
slaveCollections[i].addEventListener(CollectionEvent.COLLECTION_CHANGE, collectionListener);
}
...
private function collectionListener(event:CollectionEvent):void
{
if (event.kind != CollectionEventKind.REMOVE)
return
for each(var slaveCollection:ArrayCollection in slaveCollections)
{
for each(var item:Object in event.items)
{
var itemIndex:int = slaveCollection.getItemIndex(item);
if (itemIndex >= 0)
{
slaveCollection.removeItemAt(itemIndex);
}
}
}
}
This should allow you to call: collection.removeItem(x) on any of your collections and have that item removed from the other ones.

Related

How to insert data in table y that related with table x 0 - 0/1 (x,y)

Hi I am working on an EF Using Model First.
I want to add more details in table that specify for special categorys
but when I add these details that depend on adding data in a product table I get an exception.
public static void addproduct(ProductViewModel vm ,string userid)
{
var model = Mapper.Map<ProductViewModel, Product>(vm);
model.CountSell = 0;
byte[] binaries = new byte[vm.postprofilimgae.ContentLength];
vm.postprofilimgae.InputStream.Read(binaries, 0, vm.postprofilimgae.ContentLength);
model.ProfileImage = binaries;
foreach (var file in vm.postProductimages)
{
var filedetails = new ProductImage();
var data = new byte[file.ContentLength];
filedetails.ContentLength = file.ContentLength;
filedetails.FileName = file.FileName;
file.InputStream.Read(data, 0, file.ContentLength);
filedetails.ProductImage1 = data;
filedetails.ProductID= model.ProductID;
model.ProductImages.Add(filedetails);
}
using (var db = new Entities())
{
model.ActivationID = db.ActivationStatus.Single(x => x.Name == "Active").ActivationID;
model.SubCategoryID = vm.SubCategoryID;
model.EmployeeID= db.Employees.Single(x => x.UserID == userid).EmployeeID;
model.CountSell = 0;
VichDetails detailsmodel = new VichDetails();
if (db.SubCategories.Single(x=>x.SubCategoryID == vm.SubCategoryID).MainCategoryID == db.MainCategories.Single(x=> x.Name == Categories.vehicles).MainCategoryID)
{
VichDetails moredetails = new VichDetails();
detailsmodel = Mapper.Map<ProductViewModel, VichDetails>(vm);
//detailsmodel.ProductID = model.ProductID;
db.VichDetails.Add(detailsmodel);
}
db.SaveChanges();
model.VichDetailsID = detailsmodel.Id;
db.Products.Add(model);
db.SaveChanges();
}
}
I get this exception:
In your Product you will want to consider adding:
public virtual VichDetail VichDetail { get; set; }
and then instead of:
if (db.SubCategories.Single(x=>x.SubCategoryID == vm.SubCategoryID).MainCategoryID == db.MainCategories.Single(x=> x.Name == Categories.vehicles).MainCategoryID)
{
VichDetails moredetails = new VichDetails();
detailsmodel = Mapper.Map<ProductViewModel, VichDetails>(vm);
db.VichDetails.Add(detailsmodel);
}
db.SaveChanges();
model.VichDetailsID = detailsmodel.Id;
db.Products.Add(model);
db.SaveChanges();
it would look like:
if (db.SubCategories.Single(x=>x.SubCategoryID == vm.SubCategoryID).MainCategoryID == db.MainCategories.Single(x=> x.Name == Categories.vehicles).MainCategoryID)
{
VichDetails detailsmodel = Mapper.Map<ProductViewModel, VichDetails>(vm);
model.VichDetails = detailsModel;
}
db.Products.Add(model);
db.SaveChanges();
The issue you are encountering is that while you are setting the new VichDetail ID on your Product before saving the product, you have only associated the Product, not necessarily the VichDetail. I.e.
if (db.SubCategories.Single(x=>x.SubCategoryID == vm.SubCategoryID).MainCategoryID == db.MainCategories.Single(x=> x.Name == Categories.vehicles).MainCategoryID)
If this condition is false, the VichDetail is not added to the DbContext.
The code is rather confusing to look at as you are creating a VichDetail, but then checking that condition before creating another VichDetail "moredetails" which doesn't look to be used, before mapping the original details from the view model. If that condition doesn't pass you will have an empty VichDetails (detailsmodel) with likely a default ID (0?) which would be set on your Product. (model)
You cannot simply move the model.VichDetailsID = detailsmodel.id inside your conditions, since you're relying on setting FK IDs which won't be available until the related entity is saved to the DbContext. Navigation properties are generally a lot easier to interact with than messing around with PKs and FKs in your entities. Let EF do the lifting for associating the relationships.
If your entities already have these navigation properties, then you'll want to use those and avoid setting FKs directly.

Update autoComplete JavaFx?

I'm currently working on a JavaFX project.I'm using Autcomplete TextField of ControlFx .Each time i add new rows in database table, it should to update Autocomplete ,i did this but my problem is showing double Context-Menu ,we can say double autocompletes because i call method that create autocomplete each adding of new elements in table.
When i click a tab editBill i call this method :
public void showEditBill() {
if (!BillPane.getTabs().contains(EditBillTab)) {
BillPane.getTabs().add(EditBillTab);
}
SingleSelectionModel<Tab> selectionModel = BillPane.getSelectionModel();
selectionModel.select(EditBillTab);
/*it should remove the old autocomplete from textfield*/
pushBills(); //Call for cheking new items
}
pushBills method () :
public void pushBills() {
ArrayList list = new ArrayList<>();
bills = new BillHeaderDao().FindAll();
for (int i = 0; i < bills.size(); i++) {
list.add(bills.get(i).getIdClient());
}
//How can i remove the old bind before bind again
autoCompletionBinding = TextFields.bindAutoCompletion(SearchBill, SuggestionProvider.create(list));
}
How i can remove the old autocomplete and bind new automplete?
Just in any case if you need to keep instance of AutoCompletionTextFieldBinding object, thus avoiding use of:
autoCompleteBinding = TextFields.bindingAutoCompletion(TextField,List);
, which will change the instance, we could go a little bit deeper and use this:
// let's suppose initially we have this possible values:
Set<String> autoCompletions = new HashSet<>(Arrays.asList("A", "B", "C"));
SuggestionProvider<String> provider = SuggestionProvider.create(autoCompletions);
new AutoCompletionTextFieldBinding<>(textField, provider);
// and after some times, possible autoCompletions values has changed and now we have:
Set<String> filteredAutoCompletions = new HashSet<>(Arrays.asList("A", "B"));
provider.clearSuggestions();
provider.addPossibleSuggestions(filteredAutoCompletions);
So, through SuggestionProvider, we have "updated" auto completion values.
To avoid doubling of suggestions menu, don't use again (for the 2nd time):
TextFields.bindAutoCompletion(..)
In order to provide updates to the auto-complete suggestion list, retain a reference to the SuggestionProvider and update the suggestion provider instead:
TextField textField = new TextField();
SuggestionProvider suggestionProvider = SuggestionProvider.create(new ArrayList());
new AutoCompletionTextFieldBinding<>(textField, suggestionProvider);
When you want to update the suggestion list:
List<String> newSuggestions = new ArrayList();
//(add entries to list)
suggestionProvider.clearSuggestions();
suggestionProvider.addPossibleSuggestions(newSuggestions);
This will do the trick:
Instead of: TextFields.bindAutoCompletion(textField, list);
, try this:
List<String> strings = new ArrayList<>();
Then create binding between your textField with the list through:
new AutoCompletionTextFieldBinding<>(textField, SuggestionProvider.create(strings));
So any changes, including removing, from the list, will be reflected in the autoCompletion of the textField;
And you will have dynamic filtering of suggestions, showed in pop-up, when user enter some text in textField;
I had the same problem some time ago I try to do as #MaxKing mentions, but it didnt work. I managed to give it a soluciĆ³n even though I don't think it's the right way.
// Dispose the old binding and recreate a new binding
autoCompleteBinding.dispose();
autoCompleteBinding = TextFields.bindingAutoCompletion(TextField,List);
try this:
public void pushBills() {
ArrayList list = new ArrayList<>();
bills = new BillHeaderDao().FindAll();
for (int i = 0; i < bills.size(); i++) {
list.add(bills.get(i).getIdClient());
}
autoCompletionBinding.dispose();
autoCompletionBinding = TextFields.bindAutoCompletion(SearchBill, SuggestionProvider.create(list));
}

Umbraco Published Event Performance

I have a comments type structure where users are able to post replies to an Article. (One article can have many discussion replies). When a user adds a reply, I want the parent articles last updated date to also change so that the article is placed at the top of the list when viewed from the frontend indicating that it has had recent activity. To achieve this, the comment is added through a custom controller and then I have used the ContentService Published event to update the parent though am finding my event to be a bit of a bottle neck and taking up to six seconds to run
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
ContentService.Published += ContentServicePublished;
}
private void ContentServicePublished(IPublishingStrategy sender, PublishEventArgs<IContent> e)
{
foreach (var node in e.PublishedEntities)
{
//Handle updating the parent nodes last edited date to address ordering
if (node.ContentType.Alias == "DiscussionReply")
{
var contentService = new Umbraco.Core.Services.ContentService();
var parentNode = contentService.GetById(node.ParentId);
int intSiblings = parentNode.Children().Count() + 1;
if(parentNode.HasProperty("siblings"))
{
parentNode.SetValue("siblings", intSiblings);
contentService.SaveAndPublishWithStatus(parentNode, 0, false);
}
}
}
}
Is there anything obvious with this code that may be causing the performance issue?
Many thanks,
You should be using the Services Singleton for accessing the various services including ContentService.
One way to do so is to access the Services on ApplicationContext.Current like so:
var contentService = ApplicationContext.Current.Services.ContentService;
However, your bottleneck is going to be in retrieving the parent node and it's properties which requires multiple calls to the database. On top of that, you're retrieving the parent's children here:
int intSiblings = parentNode.Children().Count() + 1;
The better solution is to use the PublishedContent cache which doesn't hit the database at all and provides significantly superior performance.
If you're using a SurfaceController use it's Umbraco property (and you also have access to Services as well):
// After you've published the comment node:
var commentNode = Umbraco.TypedContent(commentNodeId);
// We already know this is a DiscussionReply node, no need to check.
int intSiblings = commentNode.Parent.Children.Count() + 1;
if (commentNode.Parent.HasProperty("siblings"))
{
// It's only now that we really need to grab the parent node from the ContentService so we can update it.
var parentNode = Services.ContentService.GetById(commentNode.ParentId);
parentNode.SetValue("siblings", intSiblings);
contentService.SaveAndPublishWithStatus(parentNode, 0, false);
}
If you're implementing a WebApi based on UmbracoApiController then the same Umbraco and Services properties are available to you there as well.
I'm using Umbraco 7.3.4 and here's my solution:
// Create a list of objects to be created or updated.
var newContentList = new List<MyCustomModel>() {
new MyCustomModel {Id: 1, Name: "Document 1", Attribute1: ...},
new MyCustomModel {Id: 2, Name: "Document 2", Attribute1: ...},
new MyCustomModel {Id: 3, Name: "Document 3", Attribute1: ...}
};
// Get old content from cache
var oldContentAsIPublishedContentList = (new UmbracoHelper(UmbracoContext.Current)).TypedContent(ParentId).Descendants("YourContentType").ToList();
// Get only modified content items
var modifiedItemIds = from x in oldContentAsIPublishedContentList
from y in newContentList
where x.Id == y.Id
&& (x.Name != y.Name || x.Attribute1 != y.Attribute1)
select x.Id;
// Get modified items as an IContent list.
var oldContentAsIContentList = ApplicationContext.Services.ContentService.GetByIds(modifiedItemIds).ToList();
// Create final content list.
var finalContentList= new List<IContent>();
// Update or insert items
foreach(var item in newContentList) {
// For each new content item, find an old IContent by the ID
// If the old IContent is found and the values are modified, add it to the finalContentList
// Otherwise, create a new instance using the API.
IContent content = oldContentAsIContentList.FirstOrDefault(x => x.Id == item.Id) ?? ApplicationContext.Services.ContentService.CreateContent(item.Name, ParentId, "YourContentType");
// Update content
content.Name = item.Name;
content.SetValue("Attribute1", item.Attribute1);
finalContentList.Add(content);
// The following code is required
content.ChangePublishedState(PublishedState.Published);
content.SortOrder = 1;
}
// if the finalContentList has some items, call the Sort method to commit and publish the changes
ApplicationContext.Services.ContentService.Sort(finalContentList);

How to handle children updates in EF

I have an action
[HttpPost]
public string Edit(Member member)
and Member has a collection of children entities ICollection<AgeBracket> AgeBrackets.
Currently I do retrieve all AgeBrackets associated with the member, mark everyone as deleted, then loop through new collection and create a new entry for each. Then I update my parent entity. It works, but there should be a better way to do it:
for example, if I would wrote SQL, I could delete all existing children with just one line
DELETE FROM AgeBrackets WHERE MemberId = #MemberId
In my situation it makes a select to retrieve existing items, then generate delete for each of them, then generate insert for each new child and then it generates update for parent.
Here is how my code looks now:
IList<AgeBracket> ageBrackets = db.AgeBrackets.Where<AgeBracket>(x => x.MemberId == member.MemberId).ToList();
foreach (AgeBracket ab in ageBrackets)
db.Entry(ab).State = EntityState.Deleted;
if (member.AgeBrackets != null)
foreach (AgeBracket ab in member.AgeBrackets)
{
ab.MemberId = member.MemberId;
db.AgeBrackets.Add(ab);
}
db.Entry(member).State = EntityState.Modified;
Initially I was trying to query existing children and compare each of them to new set, but it seems to be over-complicated.
What is the best way to update member and all it's children?
There's another way to do
var originalAgeBrackets = db.AgeBrackets.Where(x => x.MemberId == member.MemberId).ToArray();
var currentAgeBrackets = member.AgeBrackets;
foreach (var original in originalAgeBrackets) {
// check if the original age brackets were modified ou should be removed
var current = currentAgeBrackets.FirstOrDefault(c => c.AgeBracketId == original.AgeBracketId);
if(current != null) {
var entry = db.Entry(original);
entry.OriginalValues.SetValues(original);
entry.CurrentValues.SetValues(current);
} else {
db.Entry(original).State = EntityState.Deleted;
}
}
// add all age brackets not listed in originalAgeBrackets
foreach (var current in currentAgeBrackets.Where(c => !originalAgeBrackets.Select(o => o.AgeBracketId).Contains(c.AgeBracketId))) {
db.AgeBrackets.Add(current);
}
db.SaveChanges();
Unfortunately what you want to do haven't native support to EF Code First. What will help you would be EntityFramework.Extended. This will allow you to do something like:
db.AgeBrackets.Delete(a => a.MemberId == member.MemberId);
You should take care of change-tracks by yourself.
Hope it helps you.

umbraco - usercontrols - umbracoNaviHide

I know I can get the current node with 'var top = Node.GetCurrent();' but I cant seem to find where I can get the related properties, specifically 'umbracoNaviHide'. I'd like to know how to access the same data that is accessible from XSLT in a user control
To get properties you need to use the GetProperty() method.
var top = Node.GetCurrent();
top.GetProperty("umbracoNaviHide").Value;
In Umbraco 8, you will have to do something like this:
private List<NavigationListItem> GetChildNavigationList(IPublishedContent page)
{
List<NavigationListItem> listItems = null;
var childPages = page.Children.Where(i => i.IsPublished());
if (childPages != null && childPages.Any() && childPages.Count() > 0)
{
listItems = new List<NavigationListItem>();
foreach (var childPage in childPages)
{
int myTrueFalseFieldValue = 1;
if (childPage.HasProperty("umbracoNaviHide"))
{
Int32.TryParse(childPage.GetProperty("umbracoNaviHide").GetValue().ToString(), out myTrueFalseFieldValue);
//myTrueFalseFieldValue = 0 // hide the page
//myTrueFalseFieldValue = 1 // don't hide the page
string name = childPage.Name;
int test = myTrueFalseFieldValue;
}
if (myTrueFalseFieldValue == 1)
{
NavigationListItem listItem = new NavigationListItem(new NavigationLink(childPage.Url, childPage.Name));
listItem.Items = GetChildNavigationList(childPage);
listItems.Add(listItem);
}
}
}
return listItems;
}
Above code will make sure that those pages which have set there umbrachoNaviHide checkbox property to true will not be included in the navigation list.
In order to see how to make custom property: umbracoNaviHide, please search youtube for "Day11: Hide Pages from Navigation in Umbraco"

Resources