<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Alex Choroshin</title>
	<atom:link href="http://blogs.microsoft.co.il/choroshin/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.microsoft.co.il/choroshin</link>
	<description>.NET/Web Developer</description>
	<lastBuildDate>Thu, 08 Nov 2018 13:05:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.0.2</generator>
	<item>
		<title>Scheduling a non-essential work in AngularJS Using requestIdleCallback</title>
		<link>http://blogs.microsoft.co.il/choroshin/2016/09/23/scheduling-a-non-essential-work-in-angularjs-using-requestidlecallback/</link>
		<comments>http://blogs.microsoft.co.il/choroshin/2016/09/23/scheduling-a-non-essential-work-in-angularjs-using-requestidlecallback/#respond</comments>
		<pubDate>Fri, 23 Sep 2016 18:46:23 +0000</pubDate>
		<dc:creator><![CDATA[Alex Choroshin]]></dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">https://blogs.microsoft.co.il/choroshin/?p=2280386</guid>
		<description><![CDATA[Hi guys, As you all know, the browser runs on a single thread, meaning it can only do one thing at a time. so for example, every JavaScript function, handling a mouse click or just rendering an HTML, will be processed ONE by ONE, thus, some operations and processes would need to stop working while [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Hi guys,</p>
<p>As you all know, the browser runs on a single thread, meaning it can only do one thing at a time. so for example, every JavaScript function, handling a mouse click or just rendering an HTML, will be processed ONE by ONE, thus, some operations and processes would need to stop working while the first is still processed.</p>
<p>Things become more complicated when we encounter a <strong>script</strong> because, first the browser needs to download the script (if necessary) and only then will it run it. As you might have already guessed, everything else STOPS and causes the browser to become unresponsive resulting a poor user experience.</p>
<p>&nbsp;</p>
<p>What happens when we need to perform some kind of background tasks like sending analytics data while the user is still scrolling the page or pre-fetching content while the user happens to be tapping on the button?</p>
<p>&nbsp;</p>
<p>One option is to use <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers">Web Workers</a> which can run code concurrently in a separate thread, but, it also has a down-side – you’re not permitted to directly access or update the DOM.</p>
<h2></h2>
<p><span id="more-1081"></span></p>
<h2>Hello requestIdleCallback</h2>
<p>&nbsp;</p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback">requestIdleCallback</a> is a new API designed to schedule non-essential background tasks when there is either free time at the end of a frame, or when the user is inactive.<br />This means that there’s an opportunity to do your work without getting in the user’s way.</p>
<p>Since this new API is available only on Chrome 47 and above, we should check first that it’s available for use:</p>
<pre style="background: #ffffff;color: #000000"><span style="font-weight: bold;color: #800000">if</span> <span style="color: #808030">(</span><span style="color: #800000">'</span><span style="color: #0000e6">requestIdleCallback</span><span style="color: #800000">'</span> <span style="font-weight: bold;color: #800000">in</span> window<span style="color: #808030">)</span> <span style="color: #800080">{</span>
  <span style="color: #696969">// Use requestIdleCallback to schedule work.</span>
 <span style="color: #800080">}</span> <span style="font-weight: bold;color: #800000">else</span> <span style="color: #800080">{</span>
  <span style="color: #696969">// no support - do something else</span>
 <span style="font-weight: bold;color: #800000">setTimeout</span><span style="color: #808030">(</span>backgroundTask1<span style="color: #808030">,</span> <span style="color: #008c00">1</span><span style="color: #808030">)</span><span style="color: #800080">;</span>
 <span style="font-weight: bold;color: #800000">setTimeout</span><span style="color: #808030">(</span>backgroundTask2<span style="color: #808030">,</span> <span style="color: #008c00">1</span><span style="color: #808030">)</span><span style="color: #800080">;</span>
 <span style="font-weight: bold;color: #800000">setTimeout</span><span style="color: #808030">(</span>backgroundTask3<span style="color: #808030">,</span> <span style="color: #008c00">1</span><span style="color: #808030">)</span><span style="color: #800080">;</span>
 
 <span style="color: #800080">}</span>
</pre>
<ul>
<li>You can also <a href="https://developers.google.com/web/updates/2015/08/using-requestidlecallback?hl=en">shim</a> its behavior. </li>
</ul>
<h2>Using requestIdleCallback</h2>
<p>&nbsp;</p>
<p><strong>Callback:</strong></p>
<p>A reference to a function that will be called during a browser’s idle period. The callback function must take the following parameters:</p>
<ul>
<li><strong>timeRemaining</strong>: A reference to a method that returns a <a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp">DOMHighResTimeStamp</a>.
<li><strong>didTimeout</strong>: A boolean that returns true if the callback was invoked by the user agent, and false otherwise. </li>
</ul>
<p><strong>Options:</strong></p>
<p>Contains optional configuration parameters. It has the following property:</p>
<ul>
<li><strong>timeout</strong>: A deadline by which the browser must call the given callback function. This value is given in milliseconds. </li>
</ul>
<pre style="background: #ffffff;color: #000000">requestIdleCallback<span style="color: #808030">(</span>myNonEssentialWork<span style="color: #808030">)</span><span style="color: #800080">;</span>
 <span style="font-weight: bold;color: #800000">function</span> myNonEssentialWork <span style="color: #808030">(</span>deadline<span style="color: #808030">)</span> <span style="color: #800080">{</span>
   <span style="font-weight: bold;color: #800000">while</span> <span style="color: #808030">(</span>deadline<span style="color: #808030">.</span>timeRemaining<span style="color: #808030">(</span><span style="color: #808030">)</span> <span style="color: #808030">&gt;</span> <span style="color: #008c00">0</span><span style="color: #808030">)</span>
     doWorkIfNeeded<span style="color: #808030">(</span><span style="color: #808030">)</span><span style="color: #800080">;</span>
 <span style="color: #800080">}</span>
</pre>
<p>Guaranteeing your function is called:</p>
<pre style="background: #ffffff;color: #000000">requestIdleCallback<span style="color: #808030">(</span>processPendingAnalyticsEvents<span style="color: #808030">,</span> <span style="color: #800080">{</span> timeout<span style="color: #800080">:</span> <span style="color: #008c00">2000</span> <span style="color: #800080">}</span><span style="color: #808030">)</span><span style="color: #800080">;</span>
</pre>
<p>• Guaranteeing your function is called within the first two seconds.</p>
<h2></h2>
<h2>Angular Say Hello to requestIdleCallback</h2>
<p>&nbsp;</p>
<p>Since we are using requestIdleCallback API that invokes our function tasks, Angular has no clue that something has changed, so the trick here is to remember to call the <strong>$apply()</strong> function, so Angular could digest and make the appropriate changes.</p>
<p>&nbsp;</p>
<p>I have created an Angular service you could use as a starting point for your non-essential background tasks.</p>
<pre style="background: #ffffff;color: #000000">app<span style="color: #808030">.</span>factory<span style="color: #808030">(</span><span style="color: #800000">"</span><span style="color: #0000e6">backgroundTask</span><span style="color: #800000">"</span><span style="color: #808030">,</span><span style="font-weight: bold;color: #800000">function</span><span style="color: #808030">(</span>$window<span style="color: #808030">,</span>$timeout<span style="color: #808030">,</span>$rootScope<span style="color: #808030">)</span><span style="color: #800080">{</span>
 <span style="font-weight: bold;color: #800000">var</span> tasks<span style="color: #800080">;</span>
 
<span style="font-weight: bold;color: #800000">function</span> addBackgroundTasks<span style="color: #808030">(</span>taskList<span style="color: #808030">)</span><span style="color: #800080">{</span>
 tasks<span style="color: #808030">=</span>angular<span style="color: #808030">.</span>isArray<span style="color: #808030">(</span>taskList<span style="color: #808030">)</span><span style="color: #800080">?</span>taskList<span style="color: #800080">:</span><span style="color: #808030">[</span><span style="color: #808030">]</span><span style="color: #800080">;</span>
 
 <span style="font-weight: bold;color: #800000">if</span> <span style="color: #808030">(</span><span style="color: #800000">'</span><span style="color: #0000e6">requestIdleCallback</span><span style="color: #800000">'</span> <span style="font-weight: bold;color: #800000">in</span> $window<span style="color: #808030">)</span> <span style="color: #800080">{</span>
 <span style="color: #696969">// requestIdleCallback supported</span>
 requestIdleCallback<span style="color: #808030">(</span>backgroundTask<span style="color: #808030">)</span><span style="color: #800080">;</span>
<span style="color: #800080">}</span>
<span style="font-weight: bold;color: #800000">else</span> <span style="color: #800080">{</span>
 <span style="color: #696969">// no support</span>
 <span style="font-weight: bold;color: #800000">while</span> <span style="color: #808030">(</span>tasks<span style="color: #808030">.</span><span style="font-weight: bold;color: #800000">length</span><span style="color: #808030">)</span> <span style="color: #800080">{</span>
 $timeout<span style="color: #808030">(</span>task<span style="color: #808030">.</span>shift<span style="color: #808030">(</span><span style="color: #808030">)</span><span style="color: #808030">,</span> <span style="color: #008c00">1</span><span style="color: #808030">)</span><span style="color: #800080">;</span>
 <span style="color: #800080">}</span>
<span style="color: #800080">}</span>
<span style="color: #800080">}</span>


<span style="font-weight: bold;color: #800000">function</span> backgroundTask <span style="color: #808030">(</span>deadline<span style="color: #808030">)</span> <span style="color: #800080">{</span>
 <span style="color: #696969">// run next task if possible</span>
 <span style="font-weight: bold;color: #800000">while</span> <span style="color: #808030">(</span>deadline<span style="color: #808030">.</span>timeRemaining<span style="color: #808030">(</span><span style="color: #808030">)</span> <span style="color: #808030">&gt;</span> <span style="color: #008c00">0</span> <span style="color: #808030">&amp;&amp;</span> tasks<span style="color: #808030">.</span><span style="font-weight: bold;color: #800000">length</span> <span style="color: #808030">&gt;</span> <span style="color: #008c00">0</span><span style="color: #808030">)</span> <span style="color: #800080">{</span>
 <span style="font-weight: bold;color: #800000">var</span> task<span style="color: #808030">=</span>tasks<span style="color: #808030">.</span>shift<span style="color: #808030">(</span><span style="color: #808030">)</span><span style="color: #800080">;</span>
 task<span style="color: #808030">(</span><span style="color: #808030">)</span><span style="color: #800080">;</span>
 $rootScope<span style="color: #808030">.</span>$apply<span style="color: #808030">(</span><span style="color: #808030">)</span><span style="color: #800080">;</span>
 
 <span style="color: #800080">}</span>

 <span style="color: #696969">// schedule further tasks if necessary</span>
 <span style="font-weight: bold;color: #800000">if</span> <span style="color: #808030">(</span>tasks<span style="color: #808030">.</span><span style="font-weight: bold;color: #800000">length</span> <span style="color: #808030">&gt;</span> <span style="color: #008c00">0</span><span style="color: #808030">)</span> <span style="color: #800080">{</span>
 requestIdleCallback<span style="color: #808030">(</span>backgroundTask<span style="color: #808030">)</span><span style="color: #800080">;</span>
 <span style="color: #800080">}</span>
<span style="color: #800080">}</span>

<span style="font-weight: bold;color: #800000">return</span><span style="color: #800080">{</span>
 add<span style="color: #800080">:</span>addBackgroundTasks
<span style="color: #800080">}</span>

<span style="color: #800080">}</span><span style="color: #808030">)</span><span style="color: #800080">;</span>
</pre>
<p>Live example:<br /><a href="https://plnkr.co/edit/IQbYTj5DW7sSgGpNELPe?p=preview">https://plnkr.co/edit/IQbYTj5DW7sSgGpNELPe?p=preview</a></p>
<p>&nbsp;</p>
<h2>Resources</h2>
<p><a href="http://www.sitepoint.com/how-to-schedule-background-tasks-in-javascript/">How to Schedule Background Tasks in JavaScript</a> by <a href="http://www.sitepoint.com/author/craig-buckler/">Craig Buckler</a></p>
<p><a href="https://developers.google.com/web/updates/2015/08/using-requestidlecallback?hl=en">Using requestIdleCallback</a> by <a href="https://aerotwist.com/">Paul Lewis</a></p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback">https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback</a></p>
<p>&nbsp;</p>
<p>Hope you’ll find this post helpful.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/choroshin/2016/09/23/scheduling-a-non-essential-work-in-angularjs-using-requestidlecallback/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Angular &#8211; ui-grid &#8211; Dynamically Changing The File Name when Exporting CSV/PDF File</title>
		<link>http://blogs.microsoft.co.il/choroshin/2015/09/20/angular-ui-grid-dynamically-changing-the-file-name-when-exporting-csvpdf-file/</link>
		<comments>http://blogs.microsoft.co.il/choroshin/2015/09/20/angular-ui-grid-dynamically-changing-the-file-name-when-exporting-csvpdf-file/#respond</comments>
		<pubDate>Sun, 20 Sep 2015 14:09:50 +0000</pubDate>
		<dc:creator><![CDATA[Alex Choroshin]]></dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ui-grid]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/choroshin/?p=2280368</guid>
		<description><![CDATA[Hi guys, here’s a quick tip for dynamically changing CSV or PDF file name. Trying to make this work comes with a price, there are couple of steps you need to make before you can change the file name.First of all you need to inject uiGridExporterService service that holds all the export methods like load [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Hi guys, here’s a quick tip for dynamically changing CSV or PDF file name.</p>
<p>Trying to make this work comes with a price, there are couple of steps you need to make before you can change the file name.<br />First of all you need to inject <strong><a href="http://ui-grid.info/docs/#/api/ui.grid.exporter.service:uiGridExporterService" target="_blank">uiGridExporterService</a></strong> service that holds all the export methods like load data, get column headers, get export data object ,CSV content and finally you can call the <strong>downloadFile</strong> function that accepts file name as a first argument.</p>
<p>Example:</p>
</p>
<div id="codeSnippetWrapper" style="font-size: 8pt;overflow: auto;cursor: text;border-top: silver 1px solid;font-family: 'Courier New', courier, monospace;border-right: silver 1px solid;width: 97.5%;border-bottom: silver 1px solid;padding-bottom: 4px;direction: ltr;text-align: left;padding-top: 4px;padding-left: 4px;border-left: silver 1px solid;margin: 20px 0px 10px;line-height: 12pt;padding-right: 4px;background-color: #f4f4f4">
<pre id="codeSnippet" style="border-top-style: none;font-size: 8pt;overflow: visible;border-left-style: none;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4"><span style="color: #0000ff">var</span> app = angular.module(<span style="color: #006080">'app'</span>, [<span style="color: #006080">'ngAnimate'</span>, <span style="color: #006080">'ui.grid'</span>, <span style="color: #006080">'ui.grid.selection'</span>, <span style="color: #006080">'ui.grid.exporter'</span>]);<br><br>app.controller(<span style="color: #006080">'MainCtrl'</span>, [<span style="color: #006080">'$scope'</span>,<span style="color: #006080">'uiGridExporterConstants'</span>,<span style="color: #006080">'uiGridExporterService'</span>, <span style="color: #0000ff">function</span> ($scope,uiGridExporterConstants,uiGridExporterService) {<br><br>  $scope.exportCSV = <span style="color: #0000ff">function</span>(){<br>     <span style="color: #0000ff">var</span> exportService=uiGridExporterService;<br>     <span style="color: #0000ff">var</span> grid=$scope.gridApi.grid;<br>     <span style="color: #0000ff">var</span> fileName=getDate() + <span style="color: #006080">".csv"</span>;<br><br>     exportService.loadAllDataIfNeeded(grid, uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE).then(<span style="color: #0000ff">function</span>() {<br>     <span style="color: #0000ff">var</span> exportColumnHeaders = exportService.getColumnHeaders(grid, uiGridExporterConstants.VISIBLE);<br>     <span style="color: #0000ff">var</span> exportData = exportService.getData(grid, uiGridExporterConstants.ALL, uiGridExporterConstants.VISIBLE);<br>     <span style="color: #0000ff">var</span> csvContent = exportService.formatAsCsv(exportColumnHeaders, exportData, grid.options.exporterCsvColumnSeparator);<br>         exportService.downloadFile(fileName, csvContent, grid.options.exporterOlderExcelCompatibility);<br>  });<br><br>}<br>}]);</pre>
<p></div>
<p>* For changing and downloading PDF file you can use <strong>downloadPdf(fileName, docDefinition) </strong>method.</p>
<p>Live example: <a href="http://plnkr.co/edit/O44fbDiCe6Pb5vNYRVSU?p=preview" target="_blank">http://plnkr.co/edit/O44fbDiCe6Pb5vNYRVSU?p=preview</a></p>
<p>Good luck <img src="https://s.w.org/images/core/emoji/11/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/choroshin/2015/09/20/angular-ui-grid-dynamically-changing-the-file-name-when-exporting-csvpdf-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Angular &#8211; ui-grid &#8211; Programmatically Trigger Download of CSV/PDF File</title>
		<link>http://blogs.microsoft.co.il/choroshin/2015/09/19/angular-ui-grid-programmatically-trigger-download-of-csvpdf-file/</link>
		<comments>http://blogs.microsoft.co.il/choroshin/2015/09/19/angular-ui-grid-programmatically-trigger-download-of-csvpdf-file/#comments</comments>
		<pubDate>Fri, 18 Sep 2015 21:23:58 +0000</pubDate>
		<dc:creator><![CDATA[Alex Choroshin]]></dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ui-grid]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/choroshin/?p=2280361</guid>
		<description><![CDATA[Hi guys, here’s a quick tip for programmatically triggering a download of csv or pdf file. Code example: HTML: &#60;div ng-controller="MainCtrl"&#62; &#60;div ui-grid="gridOptions" ui-grid-selection ui-grid-exporter class="grid"&#62;&#60;/div&#62; &#60;br/&#62; &#60;button ng-click="downloadCSV()"&#62;Download CSV&#60;/button&#62; &#60;button ng-click="downloadPDF()"&#62;Download PDF&#60;/button&#62;&#60;/div&#62; JavaScript: Inside your controller you need to use gridApi object and call the exporter object who has the the csvExport function and [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Hi guys, here’s a quick tip for programmatically triggering a download of csv or pdf file.</p>
<p>Code example:</p>
<p><u>HTML:</u></p>
<div id="codeSnippetWrapper" style="font-size: 8pt;overflow: auto;cursor: text;border-top: silver 1px solid;font-family: 'Courier New', courier, monospace;border-right: silver 1px solid;width: 97.5%;border-bottom: silver 1px solid;padding-bottom: 4px;direction: ltr;text-align: left;padding-top: 4px;padding-left: 4px;border-left: silver 1px solid;margin: 20px 0px 10px;line-height: 12pt;padding-right: 4px;background-color: #f4f4f4">
<pre id="codeSnippet" style="border-top-style: none;font-size: 8pt;overflow: visible;border-left-style: none;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4"><span style="color: #0000ff">&lt;</span><span style="color: #800000">div</span> <span style="color: #ff0000">ng-controller</span><span style="color: #0000ff">="MainCtrl"</span><span style="color: #0000ff">&gt;</span><br>  <span style="color: #0000ff">&lt;</span><span style="color: #800000">div</span> <span style="color: #ff0000">ui-grid</span><span style="color: #0000ff">="gridOptions"</span> <span style="color: #ff0000">ui-grid-selection</span> <span style="color: #ff0000">ui-grid-exporter</span> <span style="color: #ff0000">class</span><span style="color: #0000ff">="grid"</span><span style="color: #0000ff">&gt;&lt;/</span><span style="color: #800000">div</span><span style="color: #0000ff">&gt;</span><br>  <span style="color: #0000ff">&lt;</span><span style="color: #800000">br</span><span style="color: #0000ff">/&gt;</span><br>    <span style="color: #0000ff">&lt;</span><span style="color: #800000">button</span> <span style="color: #ff0000">ng-click</span><span style="color: #0000ff">="downloadCSV()"</span><span style="color: #0000ff">&gt;</span>Download CSV<span style="color: #0000ff">&lt;/</span><span style="color: #800000">button</span><span style="color: #0000ff">&gt;</span><br>    <span style="color: #0000ff">&lt;</span><span style="color: #800000">button</span> <span style="color: #ff0000">ng-click</span><span style="color: #0000ff">="downloadPDF()"</span><span style="color: #0000ff">&gt;</span>Download PDF<span style="color: #0000ff">&lt;/</span><span style="color: #800000">button</span><span style="color: #0000ff">&gt;</span><br><span style="color: #0000ff">&lt;/</span><span style="color: #800000">div</span><span style="color: #0000ff">&gt;</span></pre>
<p></div>
<p><u>JavaScript:</u></p>
<p>Inside your controller you need to use <strong>gridApi</strong> object and call the exporter object who has the the <strong>csvExport</strong> function and <strong>pdfExport</strong> function, both function accept 2 string arguments, ‘<strong>rowTypes</strong>’ and ‘<strong>colTypes</strong>’ :</p>
<p><a href="http://ui-grid.info/docs/#/api/ui.grid.exporter.api:PublicApi" target="_blank">Public Api for exporter feature</a></p>
<div id="codeSnippetWrapper" style="font-size: 8pt;overflow: auto;cursor: text;border-top: silver 1px solid;font-family: 'Courier New', courier, monospace;border-right: silver 1px solid;width: 97.5%;border-bottom: silver 1px solid;padding-bottom: 4px;direction: ltr;text-align: left;padding-top: 4px;padding-left: 4px;border-left: silver 1px solid;margin: 20px 0px 10px;line-height: 12pt;padding-right: 4px;background-color: #f4f4f4">
<pre id="codeSnippet" style="border-top-style: none;font-size: 8pt;overflow: visible;border-left-style: none;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4">$scope.downloadCSV = <span style="color: #0000ff">function</span>(){<br>$scope.gridApi.exporter.csvExport(uiGridExporterConstants.VISIBLE,uiGridExporterConstants.ALL);<br>}<br><br>scope.downloadPDF = <span style="color: #0000ff">function</span>(){<br>$scope.gridApi.exporter.pdfExport(uiGridExporterConstants.VISIBLE,uiGridExporterConstants.ALL);<br>}</pre>
<p></div>
</p>
<p>Live example:<br /><a href="http://plnkr.co/edit/iPSpgLIczvdFghhmHXCk?p=preview" target="_blank">http://plnkr.co/edit/iPSpgLIczvdFghhmHXCk?p=preview</a></p>
<p>&nbsp;</p>
<p>good luck <img src="https://s.w.org/images/core/emoji/11/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/choroshin/2015/09/19/angular-ui-grid-programmatically-trigger-download-of-csvpdf-file/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>עד כמה אנחנו באמת מוכנים למעבר לאנגולר 2.0 ?</title>
		<link>http://blogs.microsoft.co.il/choroshin/2015/02/12/preparing-for-angular-2-0/</link>
		<comments>http://blogs.microsoft.co.il/choroshin/2015/02/12/preparing-for-angular-2-0/#comments</comments>
		<pubDate>Thu, 12 Feb 2015 14:57:40 +0000</pubDate>
		<dc:creator><![CDATA[Alex Choroshin]]></dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[hebrew]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/choroshin/?p=2280330</guid>
		<description><![CDATA[חלק א קצת היסטוריה אז איך הכל התחיל? בחודש ינואר 2014 בכנס ng-conf בשיחות ה- keynotes, הוכרז בפעם הראשונה הרעיון על בניית אנגולר .2 .מאז נעשתה עבודה נרחבת הן מצד מפתחי אנגולר והן מצד הקהילה אשר קיבלה אפשרות לקחת חלק בתהליך פיתוח ובניית אנגולר 2 ונתנה הצעות ופידבקים חשובים שבאים היישר מנסיון והעבודה היום יומית [&#8230;]]]></description>
				<content:encoded><![CDATA[<div dir="rtl"><span style="font-size: x-large"><strong><strong>חלק א</strong></strong></span></div>
<div dir="rtl"></div>
<div dir="rtl"></div>
<div dir="rtl">
<h3>קצת היסטוריה</h3>
</div>
<div dir="rtl">
<p>אז איך הכל התחיל?<br />
בחודש ינואר 2014 בכנס <a href="http://www.ng-conf.org/">ng-conf</a> בשיחות ה- <a href="https://www.youtube.com/watch?v=YbyZdFA6Qt4">keynotes</a>, הוכרז בפעם הראשונה הרעיון על בניית אנגולר .2 .מאז נעשתה עבודה נרחבת הן מצד מפתחי אנגולר והן מצד הקהילה אשר קיבלה אפשרות לקחת חלק בתהליך פיתוח ובניית אנגולר 2 ונתנה הצעות ופידבקים חשובים שבאים היישר מנסיון והעבודה היום יומית עם המערכת (הרי כל אחד מאיתנו כבר הספיק להבין את החוזקות והחולשות של המערכת הקיימת ).<br />
רק כדי לסבר את האוזן, שחרור גרסה 1.3.0 כללה למעלה מ -400 תורמים אשר הגישו נושאים, PRs, שיפור ועדכון מסמכים וכו.</p>
<p>אגב, בזמן שנכתב הפוסט הנ&#8221;ל, מתכננים כבר את גרסת <a href="http://angularjs.blogspot.co.il/2014/12/planning-angular-14.html">אנגולר 1.4</a> .<br />
במרץ 2014 קבלנו הצצה ראשונית ל<a href="http://angularjs.blogspot.co.il/2014/03/angular-20.html">מסמכי האפיון</a> של אנגולר 2 וגם במקרה הזה הקהילה נתנה את הדעת.<br />
בסוף אוקטובר 2014 בכנס <a href="http://ngeurope.org/">ng-europe</a> קבלנו הרבה פרטים על שחרור גרסה 2.0 הכוללת בין היתר <a href="https://www.youtube.com/watch?v=gNmWybAyBHI">ניתוק</a> מוחלט מגרסאות העבר 1.x , צוות אנגולר הודה בעצמו שהשינויים דיי דראסטיים, כאשר הקונספט המקורי נשמר רק המימוש ישתנה, החלטה אשר הותירה הרבה אנשים מודאגים נוכח השינוי הגדול.</p>
<p><strong>השינויים המהותיים קשורים לרכיבים הבאים:</strong></p>
<ol>
<li><strong>Controllers</strong></li>
<li><strong>Directive definition object</strong></li>
<li><strong>scope$</strong></li>
<li><strong>Modules</strong></li>
<li><strong>jqLite</strong></li>
</ol>
<p>בהמשך נדון בהרחבה על הרכיבים החדשים.</p>
<h3>יחסנו לאן?</h3>
<p>היום אנחנו נתמקד במספר שאלות עיקריות :</p>
<ol>
<li>אז למה אנחנו בכלל צריכים את אנגולר 2.0?</li>
<li>מדוע היה צריך לשבור את הגרסאות הקודמות?</li>
<li>מה בנוגע למיגרציה מ 1.x ל 2.0?</li>
<li>האם ימשיכו את התמיכה בגרסאות 1.x ?</li>
<li>איך אני עושה את המעבר הזה?</li>
</ol>
<p>אנשים שואלים את עצמם למה היה צריך לעשות שינוי כזה גדול? היה אפשר להמשיך ולשפר את הגרסאות<br />
הקיימות, למה היה צריך לשבור את הגרסה הקיימת?</p>
<p>אני אשתדל לענות על השאלה בצורה לא פילוסופית ולומר שלפעמים יש לשבור את הישן בשביל לבנות משהו חדש וטוב יותר (כן, זה נשמע נדוש אבל יש אמת בדבר).</p>
<h3>אז למה אנחנו בכלל צריכים את אנגולר 2.0?</h3>
<ol>
<li><strong>ביצועים</strong></li>
</ol>
<p>מסתבר שכאשר אנגולר יצא לאור, בערך לפני כ- 5 שנים, היעוד שלו היה שונה ממה שאנחנו מכירים היום, הכלי היה מכוון לקהל המעצבים ליצירת דפים וטפסי HTML בצורה קלה ומהירה אך מהר מאוד תפס תאוצה גם בקרב קהילת המפתחים. מאז אנגולר עבר דרך ארוכה, מפתחים התחילו להשתמש באנגולר כתשתית מרכזית וכפועל יוצא מכך קמו מערכות יותר ויותר מורכבות מה &#8220;שהכריח&#8221; את הצוות להמשיך ולפתח את אנגולר בכדי שימשיך להיות רלוונטי גם בעידן שבו הגבול בין אפליקציה לבין אתר אינטרנט הוא מטושטש וקיימת דרישה מתמדת להביא את ה- Web App שלנו לקצה גבול היכולת. עם זאת, קיימות מגבלות מאוד נוקשות לגבי השיפורים שניתן לעשות בשל הנחות שנעשו כחלק מתכנון המקורי, מגבלות הקשורות לבעיות ביצועים כתוצאה מתשתית של ה- binding וה- templating מה שמחייב את הצוות לחשוב על דרכים ואסטרטגיות חדשות על מנת לפתור בעיות אלה.</p>
<ol start="2">
<li><strong>השינוי בעולם ה- WEB</strong></li>
</ol>
<p>בוא נודה, עולם ה- web עובר שינויים ראדיקלים בשנים האחרונות, הדפדפנים החדשים שנותנים יכולת להפיק חויית משתמש וביצועים ברמה שלא הכרנו, יכולות חדשות בשפת ה- JS וכו&#8217;.<br />
אז בואו נפרט טיפה על כל ה- goodies שמצפים לנו:</p>
<ol>
<li>בראש ובראשונה אני מדבר על ה- <a href="http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts">ECMAScript 6</a> אשר בעוד מספר חודשים אמורים לסיים לעבוד על ה- spec שלו, כאשר הצפי שבשנת 2015 יהיו דפדפנים שיממשו את כל היכולות ששפת ES6 מציע לנו, יכולות כמו : Classes,Arrow Functions,Modules, Block Scopin, Promises, ועוד. כבר היום יש לנו דפדפנים שתומכים בחלק מהאפשרות ולכן ניתן להניח שהשינוי בכל הדפדנים המובילים יקרה בקרוב מאוד.</li>
</ol>
<ol start="2">
<li>השינוי לא קורה רק ב- JS, איגוד ה -W3C עובד על ה- <a href="http://www.w3.org/wiki/WebComponents/">Web Components</a> אשר נותנים לנו יכולת ליצור reusable component .</li>
</ol>
<p>ה- Web Components מתחלקים למספר חלקים:</p>
<ul>
<li><a href="http://w3c.github.io/webcomponents/spec/custom/">Custom Elements</a> &#8211; מאפשר הרחבת ה- HTML באמצעות תגים מותאמים אישית.</li>
<li><a href="http://w3c.github.io/webcomponents/spec/shadow/">Shadow DOM</a> &#8211; מאפשר אינקפסולציה של ה- DOM וה- CSS.</li>
<li><a href="http://w3c.github.io/webcomponents/spec/imports/">HTML Imports</a> &#8211; בדומה ל directives של אנגולר,גם כאן יש אריזה של resources שונים (HTML, CSS, JS, וכו &#8216;).</li>
<li><a href="http://www.w3.org/TR/html-templates/">Template Element</a> &#8211; בשלב זה בגדר המלצה.</li>
</ul>
<p>תשתיות ה- binding ברוב ה- frameworks ואנגולר 1.X בפרט, אינן ערוכות מספיק בשביל לעבוד עם אלמנטים רבים ולכן בשביל שצוות האנגולר יוכלו לנצל את ה- Web Components במלואם, יש צורך במימוש חדש של ה- databinding.</p>
<ol start="3">
<li><strong>מובייל</strong></li>
</ol>
<p>היום הטלפונים נמצאים בכל מקום, אם המערכת אינה נתמכת בטלפון או במילים אחרות אינה היברידית, היא נחשבת למערכת ארכאית ולא רלוונטית, היום יש הרבה מאוד Mobile Apps שרצים על אנגולר, יש אפילו framework מבוסס <a href="http://cordova.apache.org/">Cordova</a> אשר נקרא <a href="http://ionicframework.com/">ionic</a> הנותן תשתית ותמיכה באנגולר. כאן בעצם מתחילה הבעיה, אנגולר לא תוכננתה להיות מערכת היברידית לבניית Mobile Apps, עקב בעיות שקשורות לביצועים, cache ל &#8211;  pre-compiled views, בעיות routing וכו. זאת הסיבה שאפלקציות רציניות אשר מבוססות אנגולר לא רצות בצורה חלקה במובייל, כמובן שיש דברים שניתן להוסיף לשפר אך רוב דברים המחייבים שינוי תשתית .</p>
<h3>מדוע היה צריך לשבור את הגרסאות הקודמות?</h3>
<p>כפי שאתם רואים, עולם ה-Web מציב בפנינו אתגרים חדשים ומלהיבים, עולם שבו אינך מצליח למצמץ מבלי שמשהו חדש יצוץ ויפתיע אותנו מחדש. מגמת ההתחדשות הזאת הביאה אותנו למצב שאם אינך מחובר ולא מעודכן במה שקורה סביבך, אתה פשוט לא לרלוונטי, זאת בדיוק התפיסה שמניע את צוות אנגולר להמשיך ולפתח את גרסת 2.0, כי אם ה- framework אינו מסוגל לתמוך ברכיבי ה JS החדשים ,אינו מסוגל לעבוד עם רכיבי ה- Web Components , לא מתאים לעבודה עם מובייל ולא מצליח לנצל את היכולות החדשות של ה-Web, הוא פשוט לא ישרוד!.</p>
<p>אנגולר 2.0 מנסה לתת מענה וללכת יד ביד עם הטכנולוגיה שלא מפסיקה להשתנות ולהמציא את עצמה מחדש, כפי שכבר נאמר קודם, בשביל להשיג את המטרה הזאת, יש צורך לשנות גישה\אסטרטגיה ולשכתב הרבה דברים בשביל להתאים ולעמוד בסטנדרט.</p>
<p><strong>בחלק ב נמשיך את הדיון לגבי המעבר עצמו וננסה להבין עד כמה באמת יהיה קשה לבצע אותו.</strong></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/choroshin/2015/02/12/preparing-for-angular-2-0/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Angular &#8211; Numeric Control Directive</title>
		<link>http://blogs.microsoft.co.il/choroshin/2014/07/03/angular-angular-numeric-control/</link>
		<comments>http://blogs.microsoft.co.il/choroshin/2014/07/03/angular-angular-numeric-control/#comments</comments>
		<pubDate>Wed, 02 Jul 2014 21:34:41 +0000</pubDate>
		<dc:creator><![CDATA[Alex Choroshin]]></dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[Directive]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JQuery]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/choroshin/?p=2280290</guid>
		<description><![CDATA[in one of LogoUi’s projects we had a requirement for&#160; a numeric input type.My first thought was using an HTML5 input type number . Example: &#60;input type="number" min="1" max="5"&#62; The problem was that not all browsers has support for HTML5 input types.Check this site for more information about HTML5 forms browser support . so as [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>in one of <a href="http://logoui.co.il/">LogoUi</a>’s projects we had a requirement for&nbsp; a numeric input type.<br />My first thought was using an HTML5 input type number .</p>
<p>Example:</p>
<div id="codeSnippetWrapper" style="font-size: 8pt;overflow: auto;cursor: text;border-top: silver 1px solid;font-family: 'Courier New', courier, monospace;border-right: silver 1px solid;width: 97.5%;border-bottom: silver 1px solid;padding-bottom: 4px;direction: ltr;text-align: left;padding-top: 4px;padding-left: 4px;border-left: silver 1px solid;margin: 20px 0px 10px;line-height: 12pt;padding-right: 4px;background-color: #f4f4f4">
<pre id="codeSnippet" style="border-top-style: none;font-size: 8pt;overflow: visible;border-left-style: none;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4"><span style="color: #0000ff">&lt;</span><span style="color: #800000">input</span> <span style="color: #ff0000">type</span><span style="color: #0000ff">="number"</span>  <span style="color: #ff0000">min</span><span style="color: #0000ff">="1"</span> <span style="color: #ff0000">max</span><span style="color: #0000ff">="5"</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>The problem was that not all browsers has support for HTML5 input types.<br />Check <a href="http://www.wufoo.com/html5/" target="_blank">this</a> site for more information about HTML5 forms browser support .</p>
<p>so as a solution I decided to do 2 things:</p>
<p>A) Use jQuery <a href="http://jqueryui.com/spinner/" target="_blank">Spinner</a> (numeric) widget which solves my cross browser compatibility issue.<br />B) Wrap the widget as an Angular directive.</p>
<p>Final Result:</p>
<p><a href="http://embed.plnkr.co/o33VP56azuA22FLjpU3p/preview" target="_blank">http://embed.plnkr.co/o33VP56azuA22FLjpU3p/preview</a>
</p>
<p>You can find my source code and more examples regarding Numeric directive in my <a href="https://github.com/choroshin/angular-ui-numeric" target="_blank">GitHub</a> page.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/choroshin/2014/07/03/angular-angular-numeric-control/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ng-grid &#8211; Dynamically Setting Group by One or More Fields</title>
		<link>http://blogs.microsoft.co.il/choroshin/2014/06/17/ng-grid-dynamically-setting-group-by-one-column-or-more/</link>
		<comments>http://blogs.microsoft.co.il/choroshin/2014/06/17/ng-grid-dynamically-setting-group-by-one-column-or-more/#comments</comments>
		<pubDate>Tue, 17 Jun 2014 11:21:25 +0000</pubDate>
		<dc:creator><![CDATA[Alex Choroshin]]></dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ng-grid]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/choroshin/?p=2280255</guid>
		<description><![CDATA[in one of LogoUi’s projects we had a requirement for dynamically grouping data,&#160; trying to dynamically group data using the group property , is ignored, so after examining the ng-grid internal code, i found a solution. Setting group by one field for grouping by one field, in grid options object you need to call the [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>in one of <a href="http://logoui.co.il/" target="_blank">LogoUi</a>’s projects we had a requirement for dynamically grouping data,&nbsp; trying to dynamically group data using the <strong>group</strong> property , is ignored, so after examining the ng-grid internal code, i found a solution.  </p>
<p><font size="4"><strong><u>Setting group by one field</u></strong></font>  </p>
<p>for grouping by one field, in grid options object you need to call the <strong>groupBy</strong> function and pass the field as a string argument .  </p>
<p><u>Example:<br /></u><br />html:</p>
<div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:38a7a988-3a09-4f51-ad74-1a0cdcaea955" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px">
<pre style="background-color:#FFFFFF;overflow: auto"><span style="color: #0000FF">&lt;</span><span style="color: #800000">div </span><span style="color: #FF0000">ng-controller</span><span style="color: #0000FF">="MyCtrl"</span><span style="color: #0000FF">&gt;</span><span style="color: #000000">
</span><span style="color: #0000FF">&lt;</span><span style="color: #800000">button </span><span style="color: #FF0000">type</span><span style="color: #0000FF">="button"</span><span style="color: #FF0000"> ng-click</span><span style="color: #0000FF">="changeGroupBy('name')"</span><span style="color: #0000FF">&gt;</span><span style="color: #000000">Group By Name</span><span style="color: #0000FF">&lt;/</span><span style="color: #800000">button</span><span style="color: #0000FF">&gt;</span><span style="color: #000000">
</span><span style="color: #0000FF">&lt;</span><span style="color: #800000">button </span><span style="color: #FF0000">type</span><span style="color: #0000FF">="button"</span><span style="color: #FF0000"> ng-click</span><span style="color: #0000FF">="changeGroupBy('age')"</span><span style="color: #0000FF">&gt;</span><span style="color: #000000">Group By Age</span><span style="color: #0000FF">&lt;/</span><span style="color: #800000">button</span><span style="color: #0000FF">&gt;</span><span style="color: #000000">
</span><span style="color: #0000FF">&lt;</span><span style="color: #800000">div </span><span style="color: #FF0000">class</span><span style="color: #0000FF">="gridStyle"</span><span style="color: #FF0000">  ng-grid</span><span style="color: #0000FF">="gridOptions"</span><span style="color: #0000FF">&gt;&lt;/</span><span style="color: #800000">div</span><span style="color: #0000FF">&gt;</span><span style="color: #000000">
</span><span style="color: #0000FF">&lt;/</span><span style="color: #800000">div</span><span style="color: #0000FF">&gt;</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>JavaScript:</p>
<div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:b7c13b17-30d6-4b20-afd6-8add88b0bbfa" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px">
<pre style="background-color:#FFFFFF;overflow: auto"><span style="color: #000000">app.controller(</span><span style="color: #000000">'</span><span style="color: #000000">MyCtrl</span><span style="color: #000000">'</span><span style="color: #000000">, </span><span style="color: #0000FF">function</span><span style="color: #000000">($scope) {

    $scope.myData </span><span style="color: #000000">=</span><span style="color: #000000"> [{</span><span style="color: #000000">"</span><span style="color: #000000">name</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">"</span><span style="color: #000000">Moroni</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">age</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">50</span><span style="color: #000000">},
              {</span><span style="color: #000000">"</span><span style="color: #000000">name</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">"</span><span style="color: #000000">Tiancum</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">age</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">53</span><span style="color: #000000">},
              {</span><span style="color: #000000">"</span><span style="color: #000000">name</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">"</span><span style="color: #000000">Jacob</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">age</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">27</span><span style="color: #000000">},
              {</span><span style="color: #000000">"</span><span style="color: #000000">name</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">"</span><span style="color: #000000">Nephi</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">age</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">54</span><span style="color: #000000">},
              {</span><span style="color: #000000">"</span><span style="color: #000000">name</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">"</span><span style="color: #000000">Alex</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">age</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">53</span><span style="color: #000000">},
              {</span><span style="color: #000000">"</span><span style="color: #000000">name</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">"</span><span style="color: #000000">Jhonny</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">age</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">22</span><span style="color: #000000">},
              {</span><span style="color: #000000">"</span><span style="color: #000000">name</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">"</span><span style="color: #000000">Ben</span><span style="color: #000000">"</span><span style="color: #000000">, </span><span style="color: #000000">"</span><span style="color: #000000">age</span><span style="color: #000000">"</span><span style="color: #000000">: </span><span style="color: #000000">11</span><span style="color: #000000">},
              ],

    $scope.gridOptions </span><span style="color: #000000">=</span><span style="color: #000000"> { 
        data: </span><span style="color: #000000">'</span><span style="color: #000000">myData</span><span style="color: #000000">'</span><span style="color: #000000">
        };

    $scope.changeGroupBy </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000FF">function</span><span style="color: #000000"> (group) {
     $scope.gridOptions.groupBy(group);
   }
});</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>Live Example:</p>
<p><iframe style="height: 300px;width: 100%" src="http://embed.plnkr.co/A0q3c98s8K4h3n83MULE/preview"></iframe></p>
<p><font size="4"><strong><u>Setting group by array of fields</u></strong></font> </p>
<p>Grouping by array of fields, it’s a little bit tricky, internally ng-grid has the following function:</p>
</p>
<div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:72413ca4-a19e-4a33-9608-73cc3a3942fe" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px">
<pre style="background-color:#FFFFFF;overflow: auto"><span style="color: #008000">//</span><span style="color: #008000"> method for user to set the groups programatically</span><span style="color: #008000">
</span><span style="color: #000000">options.groupBy </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000FF">function</span><span style="color: #000000"> (field) {
    </span><span style="color: #0000FF">if</span><span style="color: #000000"> (field) {
        $scope.groupBy($scope.columns.filter(</span><span style="color: #0000FF">function</span><span style="color: #000000">(c) {
            </span><span style="color: #0000FF">return</span><span style="color: #000000"> c.field </span><span style="color: #000000">===</span><span style="color: #000000"> field;
        })[</span><span style="color: #000000">0</span><span style="color: #000000">]);
    } </span><span style="color: #0000FF">else</span><span style="color: #000000"> {
        </span><span style="color: #0000FF">var</span><span style="color: #000000"> arr </span><span style="color: #000000">=</span><span style="color: #000000"> $.extend(</span><span style="color: #0000FF">true</span><span style="color: #000000">, [], $scope.configGroups);
        angular.forEach(arr, $scope.groupBy);
    }
};</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>as you can see, ng-grid has a little bug, because when trying to pass an array of field names, there is no check for field value to be an array and as a result the first condition executes and we get the following error: <font color="#ff0000">TypeError: Cannot read property &#8216;groupable&#8217; of undefined</font><font color="#000000">.</p>
<p>so in order to get our code working (without changing ng-grid internally), we need to add our field names to <strong>$scope.configGroups</strong> array, then pass an empty/null/undefined argument so the second condition could kick in, start iterating each item in the <strong>$scope.configGroups</strong> array and start grouping it.</p>
<p>Example:</font></p>
<div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:d61f53c2-e68b-4dc8-9e63-c50f65a35e6e" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px">
<pre style="background-color:#FFFFFF;overflow: auto"><span style="color: #000000">$scope.changeGroupBy </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000FF">function</span><span style="color: #000000"> (group1,group2) {
  $scope.gridOptions.$gridScope.configGroups</span><span style="color: #000000">=</span><span style="color: #000000">[];
  $scope.gridOptions.$gridScope.configGroups.push(group1);
  $scope.gridOptions.$gridScope.configGroups.push(group2);
  $scope.gridOptions.groupBy();
}</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p><font color="#000000">Live Example:</font></p>
<p><font color="#000000"><iframe style="height: 300px;width: 100%" src="http://embed.plnkr.co/fqTvmVY9U6OMSGZENJOn/preview"></iframe></font><font color="#000000"></font></p>
<p><font color="#000000"></p>
<p>* For clearing grouping, empty the <strong>$scope.configGroups</strong> array and call the <strong>groupBy</strong> method by passing an empty/null/undefined argument .</p>
<p>Example:<br /></font><font color="#000000"></font></p>
<div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:f9f32d45-16e3-42b3-aa9b-42a590756ccc" class="wlWriterEditableSmartContent" style="float: none;padding-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px">
<pre style="background-color:#FFFFFF;overflow: auto"><span style="color: #000000">   $scope.clearGroupBy</span><span style="color: #000000">=</span><span style="color: #0000FF">function</span><span style="color: #000000">(){
       $scope.gridOptions.$gridScope.configGroups</span><span style="color: #000000">=</span><span style="color: #000000">[];
       $scope.gridOptions.groupBy();
    }</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p><font color="#000000"></p>
<p>Hope you’ll find this post helpful.</font></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/choroshin/2014/06/17/ng-grid-dynamically-setting-group-by-one-column-or-more/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SharePoint 2013 &#8211; Add and Remove Link Items From Search Navigation Using PowerShell</title>
		<link>http://blogs.microsoft.co.il/choroshin/2014/05/11/sharepoint-2013-add-and-remove-items-from-search-navigation-using-powershell/</link>
		<comments>http://blogs.microsoft.co.il/choroshin/2014/05/11/sharepoint-2013-add-and-remove-items-from-search-navigation-using-powershell/#comments</comments>
		<pubDate>Sat, 10 May 2014 21:41:46 +0000</pubDate>
		<dc:creator><![CDATA[Alex Choroshin]]></dc:creator>
				<category><![CDATA[DEV]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[SharePoint 2013]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/choroshin/?p=2280240</guid>
		<description><![CDATA[Here’s a quick tip on how to add link items to SharePoint 2013 search navigation and how to remove items from search navigation. Add Items: $sites=Get-SPsite http://testsite -Limit all &#124; Get-SPweb $node1 = new-object -TypeName "Microsoft.SharePoint.Navigation.SPNavigationNode" -ArgumentList "Link1", "http://site/sites/Search/Pages/pageA.aspx", $true $node2 = new-object -TypeName "Microsoft.SharePoint.Navigation.SPNavigationNode" -ArgumentList "Link2", "http://site/sites/Search/Pages/PageB.aspx", $true $node3 = new-object -TypeName "Microsoft.SharePoint.Navigation.SPNavigationNode" -ArgumentList [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Here’s a quick tip on how to add link items to SharePoint 2013 search navigation and how to remove items from search navigation.</p>
<p><strong>Add Items:</strong></p>
<div id="codeSnippetWrapper" style="overflow: auto;cursor: text;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 97.5%;direction: ltr;text-align: left;margin: 20px 0px 10px;line-height: 12pt;background-color: #f4f4f4;border: silver 1px solid;padding: 4px">
<pre id="codeSnippet" style="overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;color: black;direction: ltr;text-align: left;margin: 0em;line-height: 12pt;background-color: #f4f4f4;border-style: none;padding: 0px">$sites=Get-SPsite http:<span style="color: #008000">//testsite -Limit all | Get-SPweb</span>
$node1 = <span style="color: #0000ff">new</span>-<span style="color: #0000ff">object</span>  -TypeName <span style="color: #006080">"Microsoft.SharePoint.Navigation.SPNavigationNode"</span>  -ArgumentList <span style="color: #006080">"Link1"</span>, <span style="color: #006080">"http://site/sites/Search/Pages/pageA.aspx"</span>, $<span style="color: #0000ff">true</span>
$node2 = <span style="color: #0000ff">new</span>-<span style="color: #0000ff">object</span>  -TypeName <span style="color: #006080">"Microsoft.SharePoint.Navigation.SPNavigationNode"</span>  -ArgumentList <span style="color: #006080">"Link2"</span>, <span style="color: #006080">"http://site/sites/Search/Pages/PageB.aspx"</span>, $<span style="color: #0000ff">true</span>
$node3 = <span style="color: #0000ff">new</span>-<span style="color: #0000ff">object</span>  -TypeName <span style="color: #006080">"Microsoft.SharePoint.Navigation.SPNavigationNode"</span>  -ArgumentList <span style="color: #006080">"Link3"</span>, <span style="color: #006080">"http://site/sites/Search/Pages/PageC.aspx"</span>, $<span style="color: #0000ff">true</span>
<span style="color: #0000ff">foreach</span> ($web <span style="color: #0000ff">in</span> $sites)
{
 $web.Navigation.SearchNav.AddAsFirst($node1)
 $web.Navigation.SearchNav.AddAsFirst($node2)
 $web.Navigation.SearchNav.AddAsFirst($node3)
}</pre>
</div>
<p><strong>Remove items:</strong></p>
<div id="codeSnippetWrapper" style="overflow: auto;cursor: text;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 97.5%;direction: ltr;text-align: left;margin: 20px 0px 10px;line-height: 12pt;background-color: #f4f4f4;border: silver 1px solid;padding: 4px">
<pre id="codeSnippet" style="overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;color: black;direction: ltr;text-align: left;margin: 0em;line-height: 12pt;background-color: #f4f4f4;border-style: none;padding: 0px">$navItems=@();
$sites=Get-SPsite http:<span style="color: #008000">//testsite -Limit all | Get-SPweb</span>
<span style="color: #0000ff">foreach</span>($web <span style="color: #0000ff">in</span> $sites){

$navs = $web.Navigation.SearchNav
   <span style="color: #0000ff">foreach</span> ($nav <span style="color: #0000ff">in</span> $navs)
   {
    $nodeid =$web.Navigation.GetNodeById($nav.Id)
    $idItems+=$nodeid
    write-host <span style="color: #006080">"add id $($nodeid.Id) to array"</span>  
   }   
   <span style="color: #0000ff">foreach</span> ($node <span style="color: #0000ff">in</span> $navItems)
   {
    $web.Navigation.SearchNav.delete($node)
    write-host <span style="color: #006080">"delete id $($node.Id)"</span>    
   }     
  $web.update()   
}</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/choroshin/2014/05/11/sharepoint-2013-add-and-remove-items-from-search-navigation-using-powershell/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ng-grid &#8211; Single Row Selection for Multiple Checkbox Plugin</title>
		<link>http://blogs.microsoft.co.il/choroshin/2014/05/05/ng-grid-single-row-selection-for-multiple-checkbox-plugin/</link>
		<comments>http://blogs.microsoft.co.il/choroshin/2014/05/05/ng-grid-single-row-selection-for-multiple-checkbox-plugin/#comments</comments>
		<pubDate>Sun, 04 May 2014 23:34:58 +0000</pubDate>
		<dc:creator><![CDATA[Alex Choroshin]]></dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ng-grid]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/choroshin/?p=2280213</guid>
		<description><![CDATA[After working with ng-grid for awhile, I realized that single selection property is missing on configuration options when&#160; multiple checkbox select (“select all” checkbox) is needed.I know it’s confusing, so lets take one step at a time and demonstrate what i mean, we’ll take a simple ng-grid and add the showSelectionCheckbox property. $scope.gridOptions = { [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>After working with <a href="http://angular-ui.github.io/ng-grid/" target="_blank">ng-grid</a> for awhile, I realized that single selection property is missing on configuration options when&nbsp; multiple checkbox select (“select all” checkbox) is needed.<br />I know it’s confusing, so lets take one step at a time and demonstrate what i mean, we’ll take a simple ng-grid and add the <strong>showSelectionCheckbox </strong>property.</p>
<div id="codeSnippetWrapper" style="overflow: auto;cursor: text;font-size: 8pt;border-top: silver 1px solid;font-family: 'Courier New', courier, monospace;border-right: silver 1px solid;width: 97.5%;border-bottom: silver 1px solid;padding-bottom: 4px;direction: ltr;text-align: left;padding-top: 4px;padding-left: 4px;margin: 20px 0px 10px;border-left: silver 1px solid;line-height: 12pt;padding-right: 4px;background-color: #f4f4f4">
<pre id="codeSnippet" style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4">$scope.gridOptions = {
   data: <span style="color: #006080">'myData'</span>,
   showSelectionCheckbox: <span style="color: #0000ff">true</span>
 };</pre>
<p>&nbsp;</p>
</div>
<p>Live example:</p>
<p><iframe height="240" src="http://embed.plnkr.co/48BlYV/preview" width="100%"></iframe></p>
<p>as you can see by default you have a multiple select but it’s not the desired result since we want a single row select, okay, so lets add the <strong>multiSelect </strong>property and set it to false.</p>
<div id="codeSnippetWrapper" style="overflow: auto;cursor: text;font-size: 8pt;border-top: silver 1px solid;font-family: 'Courier New', courier, monospace;border-right: silver 1px solid;width: 97.5%;border-bottom: silver 1px solid;padding-bottom: 4px;direction: ltr;text-align: left;padding-top: 4px;padding-left: 4px;margin: 20px 0px 10px;border-left: silver 1px solid;line-height: 12pt;padding-right: 4px;background-color: #f4f4f4">
<pre id="codeSnippet" style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4">$scope.gridOptions = {
  data: <span style="color: #006080">'myData'</span>,
  showSelectionCheckbox: <span style="color: #0000ff">true</span>,
  multiSelect: <span style="color: #0000ff">false</span>,
};</pre>
<p>&nbsp;</p>
</div>
<p>Live example:</p>
<p><iframe height="240" src="http://embed.plnkr.co/lgYdtb/preview" width="100%"></iframe></p>
<p>Great, now we have a single select, but we lost the “select all” checkbox.</p>
<p>That&#8217;s why I decided to create the single selection plugin and as a bonus i also emit the selected row event called <strong>ngGridEventRowSeleted </strong>to anyone who decides to listen to it.<br />All you need to do is to set the <strong>showSelectionCheckbox</strong> and <strong>selectWithCheckboxOnly </strong>properties to true and of course don’t forget to add my plugin.</p>
<div id="codeSnippetWrapper" style="overflow: auto;cursor: text;font-size: 8pt;border-top: silver 1px solid;font-family: 'Courier New', courier, monospace;border-right: silver 1px solid;width: 97.5%;border-bottom: silver 1px solid;padding-bottom: 4px;direction: ltr;text-align: left;padding-top: 4px;padding-left: 4px;margin: 20px 0px 10px;border-left: silver 1px solid;line-height: 12pt;padding-right: 4px;background-color: #f4f4f4">
<pre id="codeSnippet" style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4">$scope.gridOptions = { 
  data: <span style="color: #006080">'myData'</span>,
  showSelectionCheckbox: <span style="color: #0000ff">true</span>,
  selectWithCheckboxOnly : <span style="color: #0000ff">true</span>,
 plugins:[<span style="color: #0000ff">new</span> ngGridSingleSelectionPlugin()]
};
<span style="color: #008000">//listen for selected row event</span>
$scope.$on(<span style="color: #006080">'ngGridEventRowSeleted'</span>,<span style="color: #0000ff">function</span>(<span style="color: #0000ff">event</span>,row){
$scope.selectedRow=row;
})</pre>
<p>&nbsp;</p>
</div>
<p>Live example:</p>
<p><iframe height="240" src="http://embed.plnkr.co/pEzqc8XVqunaMlkf54Ti/preview" width="100%"></iframe></p>
<p>Plugin Code:</p>
<div id="codeSnippetWrapper" style="overflow: auto;cursor: text;font-size: 8pt;border-top: silver 1px solid;font-family: 'Courier New', courier, monospace;border-right: silver 1px solid;width: 97.5%;border-bottom: silver 1px solid;padding-bottom: 4px;direction: ltr;text-align: left;padding-top: 4px;padding-left: 4px;margin: 20px 0px 10px;border-left: silver 1px solid;line-height: 12pt;padding-right: 4px;background-color: #f4f4f4">
<pre id="codeSnippet" style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4"><span style="color: #0000ff">function</span> ngGridSingleSelectionPlugin() {
    <span style="color: #0000ff">var</span> self = <span style="color: #0000ff">this</span>;
    self.lastSelectedRow = <span style="color: #0000ff">null</span>;
    self.selectedRowItems = [];
    self.allRowItems = [];
    self.isAllRowSelected = <span style="color: #0000ff">false</span>;
    self.grid = <span style="color: #0000ff">null</span>;
    self.scope=<span style="color: #0000ff">null</span>;
    self.init = <span style="color: #0000ff">function</span> (scope, grid, services) {
        self.services = services;
        self.grid = grid;
        self.scope=scope;
        self.initNeddedProprties();
        <span style="color: #008000">// mousedown event on row selection</span>
        grid.$viewport.on(<span style="color: #006080">'mousedown'</span>, self.onRowMouseDown);
        <span style="color: #008000">// mousedown event on checkbox header selection</span>
        grid.$headerContainer.on(<span style="color: #006080">'mousedown'</span>, self.onHeaderMouseDown);
    };
    <span style="color: #008000">//init properties </span>
    self.initNeddedProprties = <span style="color: #0000ff">function</span> () {
        self.grid.config.multiSelect = <span style="color: #0000ff">true</span>;
        self.grid.config.showSelectionCheckbox = <span style="color: #0000ff">true</span>;
        self.grid.config.selectWithCheckboxOnly = <span style="color: #0000ff">true</span>;
    }
    self.onRowMouseDown = <span style="color: #0000ff">function</span> (<span style="color: #0000ff">event</span>) { 
        <span style="color: #008000">// Get the closest row element from where we clicked.</span>
        <span style="color: #0000ff">var</span> targetRow = $(<span style="color: #0000ff">event</span>.target).closest(<span style="color: #006080">'.ngRow'</span>);
        <span style="color: #008000">// Get the scope from the row element</span>
        <span style="color: #0000ff">var</span> rowScope = angular.element(targetRow).scope();
        <span style="color: #0000ff">if</span> (rowScope) {
            <span style="color: #0000ff">var</span> row = rowScope.row;
            <span style="color: #0000ff">if</span> (<span style="color: #0000ff">event</span>.target.type !== <span style="color: #006080">'checkbox'</span>) {
                <span style="color: #008000">// if  select all rows checkbox was pressed</span>
                <span style="color: #0000ff">if</span> (self.isAllRowSelected) {
                    self.selectedRowItems = self.grid.rowCache;
                }
                <span style="color: #008000">//set to false selected rows with checkbox</span>
                angular.forEach(self.selectedRowItems,<span style="color: #0000ff">function</span> (rowItem) {
                    rowItem.selectionProvider.setSelection(rowItem, <span style="color: #0000ff">false</span>);
                });
                self.selectedRowItems = [];
                <span style="color: #008000">//set to false last selected row</span>
                <span style="color: #0000ff">if</span> (self.lastSelectedRow) {
                    self.lastSelectedRow.selectionProvider.setSelection(self.lastSelectedRow, <span style="color: #0000ff">false</span>);
                }
                <span style="color: #0000ff">if</span> (!row.selected) {
                    row.selectionProvider.setSelection(row, <span style="color: #0000ff">true</span>);
                    self.lastSelectedRow = row;
                      self.scope.$emit(<span style="color: #006080">'ngGridEventRowSeleted'</span>,row);
                }
            }
            <span style="color: #0000ff">else</span> {
                <span style="color: #0000ff">if</span> (!row.selected) {
                    self.selectedRowItems.push(row);
                     self.scope.$emit(<span style="color: #006080">'ngGridEventRowSeleted'</span>,row);
                     
                }
            }
        }
    };
    <span style="color: #008000">// mousedown event for checkbox header selection</span>
    self.onHeaderMouseDown = <span style="color: #0000ff">function</span>(<span style="color: #0000ff">event</span>) {
        <span style="color: #0000ff">if</span> (<span style="color: #0000ff">event</span>.target.type === <span style="color: #006080">'checkbox'</span>) {
            <span style="color: #0000ff">if</span> (!<span style="color: #0000ff">event</span>.target.<span style="color: #0000ff">checked</span>) {
                self.isAllRowSelected = <span style="color: #0000ff">true</span>;
            } <span style="color: #0000ff">else</span> {
                self.isAllRowSelected = <span style="color: #0000ff">false</span>;
            }
        }
    }

}</pre>
<p>&nbsp;</p>
</div>
<p>You can also get this code from my <a href="https://github.com/choroshin/ng-grid/tree/master/plugins" target="_blank">github</a> repository.</p>
<p>if there’s any questions or some error you found , please leave a comment or contact me by mail: <a href="mailto:choroshin@gmail.com">choroshin@gmail.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/choroshin/2014/05/05/ng-grid-single-row-selection-for-multiple-checkbox-plugin/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>AngularJS &#8211; $$postDigest vs $timeout when DOM update is needed</title>
		<link>http://blogs.microsoft.co.il/choroshin/2014/04/08/angularjs-postdigest-vs-timeout-when-dom-update-is-needed/</link>
		<comments>http://blogs.microsoft.co.il/choroshin/2014/04/08/angularjs-postdigest-vs-timeout-when-dom-update-is-needed/#comments</comments>
		<pubDate>Mon, 07 Apr 2014 22:28:07 +0000</pubDate>
		<dc:creator><![CDATA[Alex Choroshin]]></dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/choroshin/?p=2280188</guid>
		<description><![CDATA[When you need to update the DOM once after dirty checking is over or in other words, fire a callback after the current $digest cycle completes,you can use $$postDigest or $timeout.I’ll try to explain the cons and the pros of&#160; $$postDigest and $timeout. $$postDigest&#160; pros: &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1. Fires a callback after the current $digest cycle [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>When you need to update the DOM once after dirty checking is over or in other words, fire a callback after the current $digest cycle completes,<br />you can use <strong>$$postDigest</strong> or <strong>$timeout</strong>.<br />I’ll try to explain the cons and the pros of&nbsp; $$postDigest and $timeout.</p>
<p><strong><u>$$postDigest</u></strong>&nbsp;</p>
<p><strong>pros:</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. Fires a callback after the current $digest cycle completes. </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. Great for updating the DOM once after dirty checking is over.</p>
<p><strong>cons:</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>1.<strong> $$</strong> means <strong>private</strong> to Angular, the interface is not stable.</p>
<p><strong>usage:</strong></p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<div id="codeSnippetWrapper" style="overflow: auto;cursor: text;font-size: 8pt;border-top: silver 1px solid;font-family: 'Courier New', courier, monospace;border-right: silver 1px solid;width: 97.5%;border-bottom: silver 1px solid;padding-bottom: 4px;direction: ltr;text-align: left;padding-top: 4px;padding-left: 4px;margin: 20px 0px 10px;border-left: silver 1px solid;line-height: 12pt;padding-right: 4px;background-color: #f4f4f4">
<div id="codeSnippet" style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4">
<pre style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: white"><span style="color: #008000">//runs immediately after $scope.$digest</span></pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4">$scope.$$postDigest(<span style="color: #0000ff">function</span>(){</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: white">  console.log(<span style="color: #006080">"post Digest"</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4"> });</pre>
<p><!--CRLF--></div>
</div>
</div>
</p>
<p>* it should be noted that <strong>$$postDigest</strong> wont run another digest cycle.</p>
<p><strong><u>$timeout</u></strong>&nbsp;</p>
<p><strong>pros:</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. Runs after the current $digest cycle completes. </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. Great for updating the DOM once after dirty checking is over.</p>
<p><strong>cons:</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. a little more complex to use.</p>
<p><strong>usage:<br /></strong>to prevent another digest cycle to run by default ,we need to set the third argument to <code><strong>false.</strong></code></p>
<div id="codeSnippetWrapper" style="overflow: auto;cursor: text;font-size: 8pt;border-top: silver 1px solid;font-family: 'Courier New', courier, monospace;border-right: silver 1px solid;width: 97.5%;border-bottom: silver 1px solid;padding-bottom: 4px;direction: ltr;text-align: left;padding-top: 4px;padding-left: 4px;margin: 20px 0px 10px;border-left: silver 1px solid;line-height: 12pt;padding-right: 4px;background-color: #f4f4f4">
<div id="codeSnippet" style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4">
<pre style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: white"><span style="color: #008000">//runs immediately after $scope.$digest</span></pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4">$timeout(<span style="color: #0000ff">function</span>(){</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: white"> console.log(<span style="color: #006080">"post Digest with $timeout"</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none;overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;border-bottom-style: none;color: black;padding-bottom: 0px;direction: ltr;text-align: left;padding-top: 0px;border-right-style: none;padding-left: 0px;margin: 0em;border-left-style: none;line-height: 12pt;padding-right: 0px;background-color: #f4f4f4">},0,<span style="color: #0000ff">false</span>);</pre>
<p><!--CRLF--></div>
</div>
<p>Live example:</p>
<p><iframe class="jsbin-embed" style="height: 300px;width: 100%" src="http://jsbin.com/losup/2/embed?html,js,console,output"></iframe></p>
<p>so in conclusion, the “Angular way” to make DOM updates <strong>after</strong> digest cycle, is by using a <strong>$timeout </strong>service because:<br />A) The interface is public, means there wont be any surprises.<br />B) although it’s a bit more complex to use, in the long run, <a href="http://docs.angularjs.org/api/ng/service/$timeout" target="_blank">$timeout</a> has more rich API to offer. </p>
<p><strong>Reference:<br /></strong><a title="https://docs.google.com/presentation/d/15XgHRI8Ng2MXKZqglzP3PugWFZmIDKOnlAXDGZW2Djg/edit#slide=id.p" href="https://docs.google.com/presentation/d/15XgHRI8Ng2MXKZqglzP3PugWFZmIDKOnlAXDGZW2Djg/edit#slide=id.p">https://docs.google.com/presentation/d/15XgHRI8Ng2MXKZqglzP3PugWFZmIDKOnlAXDGZW2Djg/edit#slide=id.p</a></p>
<p><a title="http://docs.angularjs.org/api/ng/service/$timeout" href="http://docs.angularjs.org/api/ng/service/$timeout">http://docs.angularjs.org/api/ng/service/$timeout</a></p>
<p>&nbsp;</p>
<p>Hope you’ll find this post helpful.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/choroshin/2014/04/08/angularjs-postdigest-vs-timeout-when-dom-update-is-needed/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>AngularJS &#8211; Why does $scope.$apply affect other scopes and how it affects performance?</title>
		<link>http://blogs.microsoft.co.il/choroshin/2014/03/29/angularjs-why-does-scope-apply-affect-other-scopes-and-how-it-affects-performance/</link>
		<comments>http://blogs.microsoft.co.il/choroshin/2014/03/29/angularjs-why-does-scope-apply-affect-other-scopes-and-how-it-affects-performance/#comments</comments>
		<pubDate>Sat, 29 Mar 2014 19:13:06 +0000</pubDate>
		<dc:creator><![CDATA[Alex Choroshin]]></dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/choroshin/?p=2280169</guid>
		<description><![CDATA[as you can see from Angular’s $apply pseudo-code: function $apply(expr) { try { return $eval(expr); } catch (e) { $exceptionHandler(e); } finally { $root.$digest(); } } Internally angular does the following: $scope.$apply = $rootScope.$digest //+ some error handling and since $scope.$apply uses $rootScope, it affects all its descendants by dirty-checking EVERY data-bound objects, it’s crazy, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>as you can see from Angular’s <strong>$apply</strong> pseudo-code:</p>
<div id="codeSnippetWrapper" style="overflow: auto;cursor: text;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 97.5%;direction: ltr;text-align: left;margin: 20px 0px 10px;line-height: 12pt;background-color: #f4f4f4;border: silver 1px solid;padding: 4px">
<pre id="codeSnippet" style="overflow: visible;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 100%;color: black;direction: ltr;text-align: left;margin: 0em;line-height: 12pt;background-color: #f4f4f4;border-style: none;padding: 0px">    <span style="color: #0000ff">function</span> $apply(expr) {
      <span style="color: #0000ff">try</span> {
        <span style="color: #0000ff">return</span> $eval(expr);
      } <span style="color: #0000ff">catch</span> (e) {
        $exceptionHandler(e);
      } <span style="color: #0000ff">finally</span> {
        $root.$digest();
      }
    }</pre>
</div>
<p>Internally angular does the following:</p>
<div id="codeSnippetWrapper" style="overflow: auto;cursor: text;font-size: 8pt;font-family: 'Courier New', courier, monospace;width: 97.5%;direction: ltr;text-align: left;margin: 20px 0px 10px;line-height: 12pt;background-color: #f4f4f4;border: silver 1px solid;padding: 4px">$scope.$apply = $rootScope.$digest //+ some error handling</div>
<p>and since <strong>$scope.$apply</strong> uses <strong>$rootScope,</strong> it affects all its descendants by dirty-checking <strong>EVERY </strong>data-bound objects, it’s crazy, a major hit on performance.</p>
<p>so If you need to update a child scope, you can call <strong>$scope.$digest</strong> to dirty-check <strong>ONLY </strong>that scope and its descendants and as a result you reduce the number of dirty-checks and increase your performance.</p>
<p>but be aware, Angular’s documentation favors $apply since it simpler to use $apply all the time and $apply has special error handling that $digest lacks.</p>
<p>Hope you’ll find this post helpful.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/choroshin/2014/03/29/angularjs-why-does-scope-apply-affect-other-scopes-and-how-it-affects-performance/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
