After 15 years of Naruto, Naruto Shippuden manga ends at chapter 700

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Siderite.DataStructures
{
/// <summary>
/// IList implementation that doesn't require a contiguous memory space (an array)
/// </summary>
/// <typeparam name="T"></typeparam>
public class BucketList<T>:IList<T>
{
private int _bucketSize;
private List<List<T>> _list;
private int _count;
/// <summary>
/// Default constructor
/// </summary>
public BucketList():this(10000)
{
_list = new List<List<T>>();
}
/// <summary>
/// Specify the bucket size (default 10000)
/// </summary>
/// <param name="bucketSize"></param>
public BucketList(int bucketSize)
{
_bucketSize = bucketSize;
}
/// <summary>
/// Create a bucket list from an IEnumerable
/// </summary>
/// <param name="enm"></param>
public BucketList(IEnumerable<T> enm):this()
{
var list = (IList<T>)this;
foreach (var itm in enm)
{
list.Add(itm);
}
}
/// <summary>
/// The item count
/// </summary>
public int Count
{
get
{
return ((IList<T>)this).Count;
}
}
#region IList<T> implementation
int IList<T>.IndexOf(T item)
{
var index = 0;
for (var i = 0; i < _list.Count; i++)
{
var idx = _list[i].IndexOf(item);
if (idx < 0)
{
index += _list[i].Count;
}
else
{
index += idx;
return index;
}
}
return -1;
}
void IList<T>.Insert(int index, T item)
{
var idx = 0;
for (var i = 0; i < _list.Count; i++)
{
var lst = _list[i];
if (index < idx + lst.Count)
{
lst.Insert(index - idx, item);
splitListIfTooLarge(i);
_count++;
return;
}
else
{
idx += lst.Count;
}
}
throw new IndexOutOfRangeException("index");
}
void IList<T>.RemoveAt(int index)
{
var idx = 0;
for (var i = 0; i < _list.Count; i++)
{
var lst = _list[i];
if (index < idx + lst.Count)
{
lst.RemoveAt(index - idx);
removeListIfEmpty(i);
_count--;
return;
}
else
{
idx += lst.Count;
}
}
throw new IndexOutOfRangeException("index");
}
T IList<T>.this[int index]
{
get
{
var idx = 0;
for (var i = 0; i < _list.Count; i++)
{
var lst = _list[i];
if (index < idx + lst.Count)
{
return lst[index - idx];
}
else
{
idx += lst.Count;
}
}
throw new IndexOutOfRangeException("index");
}
set
{
var idx = 0;
for (var i = 0; i < _list.Count; i++)
{
var lst = _list[i];
if (index < idx + lst.Count)
{
lst[index - idx]=value;
}
else
{
idx += lst.Count;
}
}
throw new IndexOutOfRangeException("index");
}
}
void ICollection<T>.Add(T item)
{
List<T> lst;
int index;
if (_list.Count == 0)
{
lst = new List<T>();
_list.Add(lst);
index=0;
}
else
{
index=_list.Count - 1;
lst = _list[index];
}
lst.Add(item);
splitListIfTooLarge(index);
_count++;
}
void ICollection<T>.Clear()
{
_list.Clear();
_count = 0;
}
bool ICollection<T>.Contains(T item)
{
return ((IList<T>)this).IndexOf(item) > -1;
}
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
{
var index = arrayIndex;
foreach (var lst in _list)
{
lst.CopyTo(array, index);
index += lst.Count;
}
}
int ICollection<T>.Count
{
get
{
return _count;
}
}
bool ICollection<T>.IsReadOnly
{
get { return false; }
}
bool ICollection<T>.Remove(T item)
{
for (var i = 0; i < _list.Count; i++)
{
var lst = _list[i];
if (lst.Remove(item))
{
_count--;
removeListIfEmpty(i);
return true;
}
}
return false;
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
foreach (var lst in _list)
{
foreach (var item in lst)
{
yield return item;
}
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ((IList<T>)this).GetEnumerator();
}
#endregion
private void splitListIfTooLarge(int listIndex)
{
var lst = _list[listIndex];
if (lst.Count > _bucketSize)
{
var newList = lst.GetRange(0, _bucketSize);
lst.RemoveRange(0, _bucketSize);
_list.Insert(listIndex, newList);
}
}
private void removeListIfEmpty(int listIndex)
{
var lst = _list[listIndex];
if (lst.Count ==0)
{
_list.RemoveAt(listIndex);
}
}
}
}
'updateSession.WebProxy.AutoDetect = true 'try this first. It doesn't work so well in some environments if no authentication windows appears (*cough* Windows 8 *cough*)
strProxy = "proxy name or address:proxy port" 'ex: 1234:999
strProxyUser = "your username"
strProxyPass = "your password"
updateSession.WebProxy.Address=strProxy
updateSession.WebProxy.UserName=strProxyUser
updateSession.WebProxy.SetPassword(strProxyPass)
Error Code: 0x80246002) and I am left angry and powerless. Well, there are options. First of all, none of the "solutions" offered by Microsoft seem to work. The most promising one (which may apply to you, but it did not apply to me) was that you may have corrupted files in the Download folder for Windows updates. As a result you need to:
Set updateSession = CreateObject("Microsoft.Update.Session")
updateSession.ClientApplicationID = "Siderite :) Sample Script"
Set updateSearcher = updateSession.CreateUpdateSearcher()
WScript.Echo "Searching for updates..." & vbCRLF
Set searchResult = _
updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")
WScript.Echo "List of applicable items on the machine:"
For I = 0 To searchResult.Updates.Count-1
Set update = searchResult.Updates.Item(I)
WScript.Echo I + 1 & "> " & update.Title
Next
If searchResult.Updates.Count = 0 Then
WScript.Echo "There are no applicable updates."
WScript.Quit
End If
WScript.Echo vbCRLF & "Creating collection of updates to download:"
Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")
For I = 0 to searchResult.Updates.Count-1
Set update = searchResult.Updates.Item(I)
addThisUpdate = false
If update.InstallationBehavior.CanRequestUserInput = true Then
WScript.Echo I + 1 & "> skipping: " & update.Title & _
" because it requires user input"
Else
If update.EulaAccepted = false Then
update.AcceptEula()
WScript.Echo I + 1 & "> Accept EULA " & update.Title
addThisUpdate = true
'WScript.Echo I + 1 & "> note: " & update.Title & " has a license agreement that must be accepted:"
'WScript.Echo update.EulaText
'WScript.Echo "Do you accept this license agreement? (Y/N)"
'strInput = WScript.StdIn.Readline
'WScript.Echo
'If (strInput = "Y" or strInput = "y") Then
' update.AcceptEula()
' addThisUpdate = true
'Else
' WScript.Echo I + 1 & "> skipping: " & update.Title & _
' " because the license agreement was declined"
'End If
Else
addThisUpdate = true
End If
End If
If addThisUpdate AND (update.MsrcSeverity = "Important" OR update.MsrcSeverity = "Critical") Then
'wscript.echo ("This item is " & update.MsrcSeverity & " and will be processed!")
Else
'comment these lines to make it download everything
wscript.echo (update.Title & " has severity [" & update.MsrcSeverity & "] and will NOT be processed!")
addThisUpdate=false
End If
If addThisUpdate = true Then
wscript.echo(I + 1 & "> adding: (" & update.MsrcSeverity & ") " & update.Title)
updatesToDownload.Add(update)
End If
Next
If updatesToDownload.Count = 0 Then
WScript.Echo "All applicable updates were skipped."
WScript.Quit
End If
WScript.Echo vbCRLF & "Downloading updates..."
Set downloader = updateSession.CreateUpdateDownloader()
downloader.Updates = updatesToDownload
downloader.Download()
Set updatesToInstall = CreateObject("Microsoft.Update.UpdateColl")
rebootMayBeRequired = false
WScript.Echo vbCRLF & "Successfully downloaded updates:"
For I = 0 To searchResult.Updates.Count-1
set update = searchResult.Updates.Item(I)
If update.IsDownloaded = true Then
WScript.Echo I + 1 & "> " & update.Title
updatesToInstall.Add(update)
If update.InstallationBehavior.RebootBehavior > 0 Then
rebootMayBeRequired = true
End If
End If
Next
If updatesToInstall.Count = 0 Then
WScript.Echo "No updates were successfully downloaded."
WScript.Quit
End If
If rebootMayBeRequired = true Then
WScript.Echo vbCRLF & "These updates may require a reboot."
End If
WScript.Echo vbCRLF & "Would you like to install updates now? (Y/N)"
strInput = WScript.StdIn.Readline
WScript.Echo
If (strInput = "Y" or strInput = "y") Then
WScript.Echo "Installing updates..."
Set installer = updateSession.CreateUpdateInstaller()
installer.Updates = updatesToInstall
Set installationResult = installer.Install()
'Output results of install
WScript.Echo "Installation Result: " & _
installationResult.ResultCode
WScript.Echo "Reboot Required: " & _
installationResult.RebootRequired & vbCRLF
WScript.Echo "Listing of updates installed " & _
"and individual installation results:"
For I = 0 to updatesToInstall.Count - 1
WScript.Echo I + 1 & "> " & _
updatesToInstall.Item(i).Title & _
": " & installationResult.GetUpdateResult(i).ResultCode
Next
End If
WScript.StdIn.Readline()
@ECHO OFF
start "Command line Windows update" cscript Update.vbs
Researchers have developed a method to produce ammonia starting only with air and water. Not only is it more energy efficient than the century-old Haber-Bosch process that’s currently in use, but it’s also greener.The article goes on to say that almost 2% of the entire world energy is used to create ammonia; making the process more efficient is great! But I have to say that this is probably just the tip of the iceberg. Lowering the production cost of such a basic article will ripple throughout many industries, lead to innovation or the possibility to use some old innovation that until now was unfeasible.
I have been working on a REST API lately and, while using Entity Framework or some other similar framework to abstract the database is certainly possible, I wanted to control every aspect of the implementation. I know, reinventing wheels, but this is how one learns. One of the most annoying bits was trying to translate some complex object from JSON to the (two dimensional) database relational tables. This post will explore my attempts and the solutions I have found.
My first attempt was straightforward: just send all types as DataTables, with some extra property to define identity and parent entity. This relies on the Microsoft Server SQL mechanism that allows sending of table variables to stored procedures. But this approach has several downsides. One of them is that in order to send a datatable to SQL you need... DataTables. As I have pointed out in several blog posts, the DataTable object is slow, and sometimes downright buggy. Even if I didn't care about performance that much, in order for SQL to receive the content of the DataTable one must create corresponding User Defined Types on the database side. Working with UDTs is very difficult for several reasons: you cannot alter a UDT (unless employing some SQL voodoo that changes system tables), you can only drop it and recreate it. This does not work if you use the UDT anywhere, so a lot of renaming needs to be done. Even if you automate the process, it's still very annoying. Then the UDT definition has to be an exact duplicate of the DataTable definition. Move some columns around and it fails. Debugging is also made difficult by the fact that the SQL profiler does not see the content of table variables when sending them to the server.
Long story short, I was looking for alternatives and I found XML. Now, you might think that this leads to a simple, and maybe even obvious, solution. But it's not that easy. Imagine that you send a list of objects in an XML. Each object is represented by an XML element and each property by a child element. In order to get the value of a property you need to do iterate through all the nodes, for each node find the properties, for each property find the one element that defines it, then get the attribute value or content of the property, all while making sure you select everything in a table. It's not that easy.
The solution I found, which simplifies the SQL code (and hopefully brings some well needed performance to the table) is to serialize the objects in a way that makes the selection simple enough. Here is an example: I have a Configuration object with an Id and a Name that also has a property called Servers, containing Server objects having an Id and a Url. Here is an example of XML serialization from the DataContractSerializer:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://schemas.datacontract.org/2004/07/SerializationTest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Id>1</Id>
<Name>Test Config</Name>
<Servers>
<Server>
<Id>1</Id>
<Url>http://some.url</Url>
</Server>
<Server>
<Id>2</Id>
<Url>http://some.other.url</Url>
</Server>
</Servers>
</Configuration>
The SQL code to get the information from an XML variable with this content would look like this:
DECLARE @Xml XML='<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://schemas.datacontract.org/2004/07/SerializationTest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Id>1</Id>
<Name>Test Config</Name>
<Servers>
<Server>
<Id>1</Id>
<Url>http://some.url</Url>
</Server>
<Server>
<Id>2</Id>
<Url>http://some.other.url</Url>
</Server>
</Servers>
</Configuration>'
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/SerializationTest')
SELECT T.Item.value('(Id/text())[1]','INT') as Id,
T.Item.value('(Name/text())[1]','NVARCHAR(100)') as Name
FROM @Xml.nodes('//Configuration') as T(Item)
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/SerializationTest')
SELECT T.Item.value('(Id/text())[1]','INT') as Id,
T.Item.value('(Url/text())[1]','NVARCHAR(100)') as Url
FROM @Xml.nodes('//Configuration/Servers/Server') as T(Item)
This works, but look at that code. In my case, the situation was worse, the object I was using was a wrapper which implemented IDictionary<string,object> and, even if it did implement ISerializable, both XmlSerializer and DataContractSerializer use the dictionary as their data and in the end I get ugly key elements and value elements that are even harder to get to and, I suppose, more inefficient to parse. Therefore I found the solution in IXmlSerializable, (yet) another serialization interface used exclusively by XML serializer classes. If every simple value would be saved as an attribute and every complex object in an element, then this could be the SQL code:
DECLARE @Xml XML='<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://schemas.datacontract.org/2004/07/SerializationTest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Config Id="1" Name="Test Config">
<Servers>
<List>
<Server Id="1" Url="http://some.url" />
<Server Id="2" Url="http://some.other.url" />
</List>
</Servers>
</Config>
</Configuration>'
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/SerializationTest')
SELECT T.Item.value('@Id','INT') as Id,
T.Item.value('@Name','NVARCHAR(100)') as Name
FROM @Xml.nodes('//Configuration/Config') as T(Item)
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/SerializationTest')
SELECT T.Item.value('@Id','INT') as Id,
T.Item.value('@Url','NVARCHAR(100)') as Url
FROM @Xml.nodes('//Configuration/Config/Servers/List/Server') as T(Item)
Much easier to read and hopefully to parse.
I am not going to write here about the actual implementation of IXmlSerializable. There are plenty of tutorials on the Internet about that. It's not pretty, :) but not too difficult, either.
What was the purpose of this exercise? Now I can send a complex object to SQL in a single query, making inserts and updates simple and not requiring at a call for each instance of each type of complex object. Now, is it fast? I have no idea. Certainly if performance is needed, perhaps the UDT/DataTable approach is faster. However you will have to define a type for each type that you send as a DataTable to a stored procedure. An alternative can be a binary serializer and a CLR SQL function that translates it into tables. However, in my project I need to easily implement very custom API methods and to control every aspect, including tracing and profiling the various SQL calls. I believe the customized IXmlSerializable/XML in SQL approach is a reasonable one.
As always, I hope this helps someone.
/// <summary>
/// It caches the property setters and getters for the public properties of a type
/// </summary>
public class TypeCache
{
private static ConcurrentDictionary<Type, TypeCache> _typeCacheDict = new ConcurrentDictionary<Type, TypeCache>();
public static TypeCache Get(Type type)
{
TypeCache cache;
if (!_typeCacheDict.TryGetValue(type, out cache))
{
cache = new TypeCache(type);
_typeCacheDict[type] = cache;
}
return cache;
}
private TypeCache(Type type)
{
Type = type;
Setters = new ConcurrentDictionary<string, Action<object, object>>();
Getters = new ConcurrentDictionary<string, Func<object, object>>();
var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
Properties = new ConcurrentDictionary<string, PropertyInfo>();
foreach (var prop in props)
{
if (prop.CanRead)
{
var objGetter = prop.GetValueGetter();
Getters[prop.Name] = objGetter.Compile();
}
if (prop.CanWrite)
{
var objSetter = prop.GetValueSetter();
Setters[prop.Name] = objSetter.Compile();
}
Properties[prop.Name] = prop;
}
}
public Type Type { get; private set; }
public ConcurrentDictionary<string, Action<object, object>> Setters { get; private set; }
public ConcurrentDictionary<string, Func<object, object>> Getters { get; private set; }
public ConcurrentDictionary<string, PropertyInfo> Properties { get; private set; }
}
public static class TypeCacheExtensions
{
/// <summary>
/// Set the value of a property by name
/// </summary>
/// <param name="cache"></param>
/// <param name="item"></param>
/// <param name="key"></param>
/// <param name="value"></param>
public static void Set<T>(this TypeCache cache, object item, string key, T value)
{
if (cache == null || item == null) return;
Action<object, object> setter;
if (!cache.Setters.TryGetValue(key, out setter)) return;
setter(item, (object)value);
}
/// <summary>
/// Get the value of a property by name
/// </summary>
/// <param name="cache"></param>
/// <param name="item"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T Get<T>(this TypeCache cache, object item, string key)
{
if (cache == null || item == null) return default(T);
Func<object, object> getter;
if (!cache.Getters.TryGetValue(key, out getter)) return default(T);
return (T)getter(item);
}
/// <summary>
/// Set the value for a property to default by name
/// </summary>
/// <param name="cache"></param>
/// <param name="item"></param>
/// <param name="key"></param>
public static void Delete(this TypeCache cache, object item, string key)
{
if (cache == null || item == null) return;
Action<object, object> setter;
if (!cache.Setters.TryGetValue(key, out setter)) return;
var value = cache.Properties[key].PropertyType.GetDefaultValue();
setter(item, value);
}
/// <summary>
/// Set the values for all the public properties of a class to their default
/// </summary>
/// <param name="cache"></param>
/// <param name="item"></param>
public static void Clear(this TypeCache cache, object item)
{
if (cache == null || item == null) return;
Action<object, object> setter;
foreach (var pair in cache.Properties)
{
if (!cache.Setters.TryGetValue(pair.Key, out setter)) continue;
var value = pair.Value.PropertyType.GetDefaultValue();
setter(item, value);
}
}
}
class Program
{
static void Main(string[] args)
{
var obj = new TestObject();
var cache = TypeCache.Get(obj.GetType());
Stopwatch sw = new Stopwatch();
sw.Start();
for (var i = 0; i < 100000; i++)
{
cache.Get<int>(obj, "TestProperty");
cache.Set<int>(obj, "TestProperty",i);
}
sw.Stop();
Console.WriteLine("Time: " + sw.Elapsed.TotalMilliseconds);
Console.ReadKey();
}
}
public static class ReflectionExtensionsWonderful thing! GetGet and GetSet :) Basically I am returning expressions that use reflection to get the getter/setter and then execute them. How long would the program with one million tries of get and set take? 1000 milliseconds. Could we improve on that?
{
public static Expression<Func<object, object>> GetValueGetter(this PropertyInfo propertyInfo)
{
var getter=propertyInfo.GetGetMethod();
return (obj) => getter.Invoke(obj, new object[] { });
}
public static Expression<Action<object, object>> GetValueSetter(this PropertyInfo propertyInfo)
{
var setter = propertyInfo.GetSetMethod();
return (obj,val) => setter.Invoke(obj, new[] { val });
}
public static object GetDefaultValue(this Type type)
{
return type.IsValueType ? Activator.CreateInstance(type) : null;
}
}
public static class ReflectionExtensions
{
/// <summary>
/// Get the expression of a value getter for a property. Compile the expression to execute or combine it with other expressions.
/// </summary>
/// <param name="propertyInfo"></param>
/// <returns></returns>
public static Expression<Func<object, object>> GetValueGetter(this PropertyInfo propertyInfo)
{
var instance = Expression.Parameter(typeof(object), "i");
var convertObj = Expression.TypeAs(instance, propertyInfo.DeclaringType);
var property = Expression.Property(convertObj, propertyInfo);
var convert = Expression.Convert(property, typeof(object));
return (Expression<Func<object, object>>)Expression.Lambda(convert, instance);
}
/// <summary>
/// Get the expression of a value setter for a property. Compile the expression to execute or combine it with other expressions.
/// </summary>
/// <param name="propertyInfo"></param>
/// <returns></returns>
public static Expression<Action<object, object>> GetValueSetter(this PropertyInfo propertyInfo)
{
var instance = Expression.Parameter(typeof(object), "i");
var argument = Expression.Parameter(typeof(object), "a");
var convertObj = Expression.TypeAs(instance, propertyInfo.DeclaringType);
var convert = Expression.Convert(argument, propertyInfo.PropertyType);
var setterCall = Expression.Call(convertObj,propertyInfo.GetSetMethod(),convert);
return (Expression<Action<object, object>>)Expression.Lambda(setterCall, instance, argument);
}
/// <summary>
/// Get the default value of a type
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static object GetDefaultValue(this Type type)
{
return type.IsValueType ? New.Instance(type) : null;
}
}
/// <summary>
/// Class used to get instances of a type
/// </summary>
public static class New
{
private static ConcurrentDictionary<Type, Func<object>> _dict = new ConcurrentDictionary<Type, Func<object>>();
public static object Instance(Type type)
{
Func<object> func;
if (!_dict.TryGetValue(type, out func))
{
func = Expression.Lambda<Func<object>>(Expression.New(type)).Compile();
_dict[type] = func;
}
return func();
}
}
<div ng-click="row.toggleExpand()" ng-style="rowStyle(row)" class="ngAggregate">
<span class="ngAggregateText">{{row.label CUSTOM_FILTERS}} ({{row.totalChildren()}} {{AggItemsLabel}})</span>
<div class="{{row.aggClass()}}"></div>
</div>
ngAggregate.prototype.totalChildren = function () {Maybe one could change the function to cover specific types of objects and return a sum instead of a count, but that is not the scope of the current post.
if (this.aggChildren.length > 0) {
var i = 0;
var recurse = function (cur) {
if (cur.aggChildren.length > 0) {
angular.forEach(cur.aggChildren, function (a) {
recurse(a);
});
} else {
i += cur.children.length;
}
};
recurse(this);
return i;
} else {
return this.children.length;
}
};
$scope.gridOptions = {Define function:
data: 'Data.Units',
enableColumnResize: true,
showColumnMenu: false,
showFilter: true,
multiSelect: false,
showGroupPanel: true,
enablePaging: false,
showFooter: true,
columnDefs: [
{ field: 'Country', displayName: 'Country', width: 190 },
{ field: 'Type', displayName: 'Unit Type' },
{ field: 'Count', displayName: 'Count', width: 180}
],
aggregateTemplate: "<div ng-click=\"row.toggleExpand()\" ng-style=\"rowStyle(row)\" class=\"ngAggregate\">" +
" <span class=\"ngAggregateText\">{{row.label CUSTOM_FILTERS}} ({{aggFunc(row)}} {{AggItemsLabel}})</span>" +
" <div class=\"{{row.aggClass()}}\"></div>" +
"</div>"
};
$scope.aggFunc = function (row) {
var sumColumn='Count';
var total = 0;
angular.forEach(row.children, function(entry) {
total+=entry.entity[sumColumn];
});
angular.forEach(row.aggChildren, function(entry) {
total+=$scope.aggFunc(entry);
});
return total;
};
module.run(["$templateCache", function($templateCache) {Now the gridOptions change to
$templateCache.put("aggregateCountTemplate.html",
"<div ng-click=\"row.toggleExpand()\" ng-style=\"rowStyle(row)\" class=\"ngAggregate\">" +
" <span class=\"ngAggregateText\">{{row.label CUSTOM_FILTERS}} ({{aggFunc(row)}} {{AggItemsLabel}})</span>" +
" <div class=\"{{row.aggClass()}}\"></div>" +
"</div>"
);
}]);
$scope.gridOptions = {and we can reuse the template anytime we want. Alternatively we can create a file and reference it, without using the cache:
[...]
aggregateTemplate: "aggregateCountTemplate.html"
};
$scope.gridOptions = {
[...]
aggregateTemplate: "/templates/aggregateCountTemplate.html"
};
var module = angular.module('app', ['ngResource', 'ui.bootstrap', 'ui', 'ngGrid', 'importTreeFilter', 'ui.date', 'SharedServices', 'ui.autocomplete']);
module.run(["$templateCache","$rootScope", function($templateCache,$rootScope) {
$rootScope.aggregateCountFunc = function (row) {
var total = 0;
angular.forEach(row.children, function(entry) {
total+=entry.entity.Count;
});
angular.forEach(row.aggChildren, function(entry) {
total+=$rootScope.aggregateCountFunc(entry);
});
return total;
};
$templateCache.put("aggregateCountTemplate.html",
"<div ng-click=\"row.toggleExpand()\" ng-style=\"rowStyle(row)\" class=\"ngAggregate\">" +
" <span class=\"ngAggregateText\">{{row.label CUSTOM_FILTERS}} ({{aggregateCountFunc(row)}}{{AggItemsLabel}})</span>" +
" <div class=\"{{row.aggClass()}}\"></div>" +
"</div>"
);
}]);