How to override or change comparator on backbone collection? [duplicate] - sorting

This question already has answers here:
correctly implement backbone comparators
(2 answers)
Closed 8 years ago.
I have a backbone collection called Topics that in one instance in my app I would like sorted by a property I have called view_count.
Another instance of the Topics collection I want to be sorted by name alphabetically.
Currently, on the collection, I have a comparator:
comparator: (topic) ->
return topic.get('view_count') * -1
When I want the collection to be sorted by name rather than view_count, what is an elegant way to override or change the comparator/sorting options? I have tried to declare the comparator function on each initialization of the Topics collection bu that doesn't seem to work correctly.

Change your collection to:
var Topics = Backbone.Collection.extend({
initialize: function(options) {
this.sortProperty = options.sortProperty;
},
comparator: function(topic) {
if(this.sortProperty == "view_count")
return topic.get("view_count") * -1;
else
return topic.get("name");
}
});
then when you instantiate your collection:
var topics1 = new Topics({sortProperty : "view_count"});
var topics2 = new Topics({sortProperty : "name"});
You can also change the sorting property after initializing a collection using:
topics1.sortProperty = "name";

Related

Linq IEqualityComparer<string> Ignore Case [duplicate]

This question already has answers here:
Case insensitive 'Contains(string)'
(29 answers)
Closed 2 years ago.
I am sorting a list of elements:
var matchEle = listOfElements.Where(e => e.Properties().Any(p => p.Name.Contains("Key", Asking for IEqualityComparer))).First();
I am used to just going straight to a StringComparer, OrdinalIgnoreCase or CurrentCultureIgnoreCase, however when calling Contains() in this context, it is asking for an IEqualityComparer. I imagine because of the data structure/level. I saw an example of how to set up an IEqualityComparer such as
strEqualityComparer = new IEqualityComparer();
and defining the class for strEqualityComparer but I am not sure beyond that. Can someone help me get my linq statement to work with an ignore case?
Update:
Just so I'm clear here is an example of the data structure:
listOfElements = [element1, element2, etc..]
element1.Properties = ["Prop1", "Key1", "Prop2", "Key2", etc.]
I need to extract the elements which pass the filter if any of its properties has a value containing the keyword, in this case "Key" therefore it cannot be .Equals or IndexOf.
Update as per comment
Search string inside another string:
var matchEle = listOfElements
.Where(e => e.Properties().Any(p => p.Name.IndexOf("Key", System.StringComparison.OrdinalIgnoreCase) >= 0))
.First();
Old solutions
You have two options, that depends on Name type:
1 - Without IEqualityComparer, and if Name in Properties is a string. replace Contains by Equals like :
var matchEle = listOfElements
.Where(e => e.Properties().Any(p => p.Name.Equals("Key", StringComparison.OrdinalIgnoreCase)))
.First();
2 - With IEqualityComparer, and if Name in Properties is a list of string:
2.1 : Create a custom comparer, like:
public class StringIEqualityComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return x.Equals(y, StringComparison.OrdinalIgnoreCase);
}
public int GetHashCode(string obj)
{
return obj.GetHashCode();
}
}
2.2 : change little your query to :
var matchEle = listOfElements
.Where(e => e.Properties().Any(p => p.Name.Contains("Key", new StringIEqualityComparer())))
.First();
I hope this helps you.

EF DbContext on a generic repository does not perform the expected includes when transforming the data into a list [duplicate]

This question already has an answer here:
EF Generic Repository Multiple Includes
(1 answer)
Closed 4 years ago.
I have a generic/base repository that I'm using and it contains different variety of methods for accessing my database.
Here's a sample:
public IQueryable<T> FindAll(string[] includedProperties = null)
{
var setContext = _context.Set<T>();
if (includedProperties != null)
{
foreach (var property in includedProperties)
{
setContext.Include(property);
}
}
return setContext;
}
I'm calling this method by:
var employees = _employeeRepository.FindAll(new string[] { "JobPosition", "Department", "EmployeeTeams", "EmployeeTeams.Team" })
When I perform a ToList() on employees, the expected navigation property is not included.
I tried switching it up and did the following:
var employees = _employeeRepository.FindAll().Include("JobPosition")
.Include("Department")
.Include("EmployeeTeams")
.Include("EmployeeTeams.Team")
And performing the ToList() includes the specified navigation property.
I want to make my approach on my generic repository work. Any ideas on how can I fix this?
NOTE: I also tried including navigation properties via expressions
(Expression<Func<T, object>> predicate[])
still the same result.
Include returns IQueryable (or IIncludableQueryable depending how you call it) so you need to add them after each other.
Try it like this
foreach (var property in includedProperties)
{
setContext = setContext.Include(property);
}

How to restrict a input field numeric in knockout js [duplicate]

This question already has answers here:
make an input only-numeric type on knockout
(10 answers)
Closed 8 years ago.
I have an input field and i want to restrict it only for numeric values. How can i do it in knockout js
here is my field
<input data-bind="value: nsc" />
You can write a function in your view model.
ko.extenders.numeric = function(target, precision) {
//create a writable computed observable to intercept writes to our observable
var result = ko.pureComputed({
read: target, //always return the original observables value
write: function(newValue) {
var current = target(),
roundingMultiplier = Math.pow(10, precision),
newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
//only write if it changed
if (valueToWrite !== current) {
target(valueToWrite);
} else {
//if the rounded value is the same, but a different value was written, force a notification for the current field
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({ notify: 'always' });
//initialize with current value to make sure it is rounded appropriately
result(target());
//return the new computed observable
return result;
};
Check this link how to use : Sample code
Guess this question is already answered.
You may need to create custom binding which accepts only allowed characters.
The answer to the post in this link will help you: make an input only-numeric type on knockout

MultiSelectList constructor

According to http://msdn.microsoft.com/en-us/library/dd470803.aspx, the MultiSelectList(IEnumerable, IEnumerable) constructor takes in two parameters: items and selectedValues.
The documentation is not completely explicit so I just want to clarify two points:
How exactly does selectedValues work? Does this constructor merely iterate through the collection and set .Selected = True for each element?
Must selectedValues be a subset of items? How is this defined, precisely (i.e. as long as their ToString values match)?
Specifically, I am playing with a jQuery multiselect plugin and am trying to do essentially what is being done in the demo of that plugin (i.e. the "selected" list is already populated by certain elements upon initialization).
The HTML:
<%=Html.ListBoxFor(model => model.tempCategories, (MultiSelectList)(ViewData["Categories"]), new {#size = "5" })%>
Controller code:
List<Categories> categoriesList = categories.Select();
ViewData["Categories"] = GenCategoryMultiList(categoriesList);
private System.Web.Mvc.MultiSelectList GenCategoryMultiList(List<TemplateCategories> entity)
{
entity = entity.OrderBy(e => e.CategoryName).ToList();
System.Web.Mvc.MultiSelectList selectList = new System.Web.Mvc.MultiSelectList(entity, "CategoryID", "CategoryName");
return selectList;
}
I am using this with JQuery Multiselect. Working code...

linqToSql related table not delay loading properly. Not populating at all

I have a couple of tables with similar relationship structure to the standard Order, OrderLine tables.
When creating a data context, it gives the Order class an OrderLines property that should be populated with OrderLine objects for that particular Order object.
Sure, by default it will delay load the stuff in the OrderLine property but that should be fairly transparent right?
Ok, here is the problem I have: I'm getting an empty list when I go MyOrder.OrderLines but when I go myDataContext.OrderLines.Where(line => line.OrderId == 1) I get the right list.
public void B()
{
var dbContext = new Adis.CA.Repository.Database.CaDataContext(
"<connectionString>");
dbContext.Connection.Open();
dbContext.Transaction = dbContext.Connection.BeginTransaction();
try
{
//!!!Edit: Imortant to note that the order with orderID=1 already exists
//!!!in the database
//just add some new order lines to make sure there are some
var NewOrderLines = new List<OrderLines>()
{
new OrderLine() { OrderID=1, LineID=300 },
new OrderLine() { OrderID=1, LineID=301 },
new OrderLine() { OrderID=1, LineID=302 },
new OrderLine() { OrderID=1, LineID=303 }
};
dbContext.OrderLines.InsertAllOnSubmit(NewOrderLines);
dbContext.SubmitChanges();
//this will give me the 4 rows I just inserted
var orderLinesDirect = dbContext.OrderLines
.Where(orderLine => orderLine.OrderID == 1);
var order = dbContext.Orders.Where(order => order.OrderID == 1);
//this will be an empty list
var orderLinesThroughOrder = order.OrderLines;
}
catch (System.Data.SqlClient.SqlException e)
{
dbContext.Transaction.Rollback();
throw;
}
finally
{
dbContext.Transaction.Rollback();
dbContext.Dispose();
dbContext = null;
}
}
So as far as I can see, I'm not doing anything particularly strange but I would think that orderLinesDirect and orderLinesThroughOrder would give me the same result set.
Can anyone tell me why it doesn't?
You're just adding OrderLines; not any actual Orders. So the Where on dbContext.Orders returns an empty list.
How you can still find the property OrderLines on order I don't understand, so I may be goofing up here.
[Edit]
Could you update the example to show actual types, especially of the order variable? Imo, it shoud be an IQueryable<Order>, but it's strange that you can .OrderLines into that. Try adding a First() or FirstOrDefault() after the Where.

Resources