Tuesday, August 8, 2017

The Three Watch Depths of AngularJS

Update: A revised version of this is now in the official Angular docs.
There are three different mechanisms for watching a value on an Angular scope: Reference watches, collection watches, and equality watches. The difference between the three is in the depth in which they watch their values.
Choosing the most appropriate watch mechanism is important, not only because the three mechanisms behave differently, but also because they have very different performance characteristics.
This short article describes the differences between the three watch depths.

Reference Watches

You register a reference watch by providing a falsy value as the third argument to $watch or by just omitting the third argument:
?
$scope.$watch(…, …, false);
or
?
$scope.$watch(…, …);
Of the three mechanisms this is the most efficient both in terms of computation and memory, since it doesn't do copying or traversal. It merely keeps a reference to the value around for comparison. The references are compared using the strict equality operator ===.
Reference watches are used internally by Angular in:

Collection Watches

You register a collection watch by calling $watchCollection:
?
$scope.$watchCollection(…, …);
Collection watches watch for changes in arrays, array-like objects, and objects. They are triggered by new, removed, replaced, and reordered items, keys, or values in those arrays and objects. They do not, however, watch the items, keys, or values themselves.
Collection watches keep an internal copy of the array or object, and traverse the old and new values in each digest cycle, checking for changes using the strict equality operator ===. The implementation attempts to avoid all unnecessary traversal. The items within the collection are just referenced, not copied.
Collection watches are used internally by Angular in the ngRepeat directive.

Equality Watches

You register an equality watch by providing a truthy value as the third argument to $watch:
?
$scope.$watch(…, …, true);
Equality watches watch for any changes within the values, which may be arbitrarily nested objects and arrays. This means they also need to keep full copies of the values around and traverse them in each digest cycle. This makes equality watches the most expensive of the three mechanisms.
Values are compared using angular.equals and copied using angular.copy.
Equality watches are used internally by Angular in the ngClass and ngStyledirectives on their attribute expressions.

-----------------------------------------------------------------------

AngularJS extends this events-loop, creating something called AngularJS context.
$watch()
Every time you bind something in the UI you insert a $watch in a $watch list.
User: <input type="text" ng-model="user" />
Password: <input type="password" ng-model="pass" />
Here we have $scope.user, which is bound to the first input, and we have $scope.pass, which is bound to the second one. Doing this we add two $watches to the $watch list.
When our template is loaded, AKA in the linking phase, the compiler will look for every directive and creates all the $watches that are needed.
AngularJS provides $watch, $watchcollection and $watch(true). Below is a neat diagram explaining all the three taken from watchers in depth.
Enter image description here
angular.module('MY_APP', []).controller('MyCtrl', MyCtrl)
function MyCtrl($scope,$timeout) {
  $scope.users = [{"name": "vinoth"},{"name":"yusuf"},{"name":"rajini"}];

  $scope.$watch("users", function() {
    console.log("**** reference checkers $watch ****")
  });

  $scope.$watchCollection("users", function() {
    console.log("**** Collection  checkers $watchCollection ****")
  });

  $scope.$watch("users", function() {
    console.log("**** equality checkers with $watch(true) ****")
  }, true);

  $timeout(function(){
     console.log("Triggers All ")
     $scope.users = [];
     $scope.$digest();

     console.log("Triggers $watchCollection and $watch(true)")
     $scope.users.push({ name: 'Thalaivar'});
     $scope.$digest();

     console.log("Triggers $watch(true)")
     $scope.users[0].name = 'Superstar';
     $scope.$digest();
  });
}

$digest loop

When the browser receives an event that can be managed by the AngularJS context the $digestloop will be fired. This loop is made from two smaller loops. One processes the $evalAsync queue, and the other one processes the $watch list. The $digest will loop through the list of $watchthat we have
app.controller('MainCtrl', function() {
  $scope.name = "vinoth";

  $scope.changeFoo = function() {
      $scope.name = "Thalaivar";
  }
});

{{ name }}
<button ng-click="changeFoo()">Change the name</button>
Here we have only one $watch because ng-click doesn’t create any watches.
We press the button.
  1. The browser receives an event which will enter the AngularJS context
  2. The $digest loop will run and will ask every $watch for changes.
  3. Since the $watch which was watching for changes in $scope.name reports a change, it will force another $digest loop.
  4. The new loop reports nothing.
  5. The browser gets the control back and it will update the DOM reflecting the new value of $scope.name
  6. The important thing here is that EVERY event that enters the AngularJS context will run a $digest loop. That means that every time we write a letter in an input, the loop will run checking every $watch in this page.

$apply()

If you call $apply when an event is fired, it will go through the angular-context, but if you don’t call it, it will run outside it. It is as easy as that. $apply will call the $digest() loop internally and it will iterate over all the watches to ensure the DOM is updated with the newly updated value.
The $apply() method will trigger watchers on the entire $scope chain whereas the $digest()method will only trigger watchers on the current $scope and its children. When none of the higher-up $scope objects need to know about the local changes, you can use $digest().

Wednesday, July 5, 2017

git bash



********  everyday do ******************
1)


$ git commit -a -m "test1"



2)
$ git push origin master






*********************************************************












==================  create a new git and upload to github ======================

$ cd //78boe99prod/ufd
$ cd D:/boe/ufd


network drive does not work with git

// add .git folder to root folder
$ git init


// add all file to git
$ git add .



// first commit
$ git commit -m "1.0"



// github.com  create new repo and copy the URL link
//    https://github.com/hoogw/ufd.git


//
$ git remote add origin https://github.com/hoogw/ufd.git


//Push the changes in your local repository to GitHub.

$ git push origin master



// login window pop up, use hoogw 4a41 



https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
==========================================================================




................................. every time commit a change and push to github ..........................

//  -a means check all change, -m means message for this commit

$ git commit -a -m "test1"


// push to github.com, no login required, since it remember the password.
$ git push origin master


...............................................................................................................................................


//-A, --all             add changes from all tracked and untracked files

$ git add -A

$ git commit -m "login"




Monday, June 5, 2017

focus 一个产品只集中,解决一个问题,

修剪花园的时候,
如果你想造一个万能工具,
只用一个工具就有多种功能,
其实这种万能工具是不存在的。

你必须用至少3种工具,每种工具只精通一个功能。
加起来,才能完成全部工作。

电锯是锯平大部分。
太粗的树枝要用钩子型的小剪刀。靠近根部的粗枝也要用这个剪。
躺在地上的细枝,或者单丁的细枝,要用19inch的长剪刀。
显然,只用电锯是无法完成所有任务的。



当一个工具是多功能的时候,
必然是每一个功能都不是很精。
结果就是功能是多,但没有一个功能做的好。做的精。

esri web app builder, geocortex, 等等,
就犯这个毛病,
想包括各种复杂的gis功能,
恨不得把所有桌面arcmap上的功能都上去,
结果就是非常复杂,没一个功能是好用的。

想包罗万象,结果一个功能都做不好。

transparent california
就很好,就做一个简单的搜索功能,很好用,很有效。
socrata open data,做的太复杂了,以后再用到
d3,做图表,更加复杂。反而不好用。

Esri的open data产品,也是太统一化,
没有个性化,所有gis数据,地址,街道,规划,。。。。全部试图用同一个模板来套用显示。
这哪里行?
因为地址的地皮,街道,本身的属性就不同。
加上同样是地址在不同场合会有不同用途。
在不同的用途场合下,当然不能用同样的模板。
一个模板一定要个性化,具体到就适用于一种用途。

esri那种一统化,一个模板,一个产品套用天下,
这种模式适合标准化,大规模生产,减低成本。
而个性化的设计,当然是高成本的。非常高的成本。

这就和建筑设计一样。
esri要一种模板,设计一次,走遍天下,低成本。大规模卖钱。
这种模式,当然就不可能个性化,
个性化,意味着,每个不同场合,设计都不同。当然是高成本的。

都是一样的衣服,都是一样的房子,
设计成本是低了,但是并不可行。

我们的路线是越简单越精。就像google只有一个功能,
搜狐,网易,21cn这些曾经的门户网站,啥都做,包罗万象,汽车,金融,理财,新闻,体育,娱乐,结果样样都不精,
百度只做一个搜索功能,只要做精了,一样超越那些门户网。

咱们只要个性化打造,一个产品一个功能,只精一个功能。
这一定是esri这些大公司没办法争过我们的地方。




Thursday, May 25, 2017

carbon forum to pdfbay

carbon forum -> pdfbay

----------------------------------------------------------------
1)C:\Apache24\htdocs\pdfbay\view\default\template\layout.php

   



  © Transparentgov.net
                            310-710-6501 huguowen@gmail.com
                     
                     
                       
                     



------------------------------------------

2)C:\Apache24\htdocs\pdfbay1\static\img\logo.png
replace logo.png


C:\Apache24\htdocs\pdfbay1\favicon.ico
replace favicon.ico


-------------------------------------------------------------------
3) ueditor file upload max size (replace whole file)

C:\Apache24\htdocs\pdfbay\library\Uploader.config.json

"fileMaxSize": 50048000, /* 上传大小限制,单位B,默认50MB */




-----------------------------------------------------------
4) avarta image, cirle to squre

C:\Apache24\htdocs\pdfbay1\static\css\default\style.css

replace all

/* border-radius: 50%; */
        border-radius: initial;


=========================================

5) switch to english,

  • C:\Apache24\htdocs\pdfbay1\config.php 
define('ForumLanguage', 'en');


----------------------------------------------------------------------------
6) ueditor switch to english

C:\Apache24\htdocs\pdfbay1\static\editor\dialogs\attachment\attachment.js

       还有2个未上传文件

   --------->
       there is 2 files not upload yet


  • C:\Apache24\htdocs\pdfbay1\static\editor\ueditor.config.js 
  •               //,lang:"zh-cn"
  •                 ,lang:"en"

Friday, March 24, 2017

crop clip basemap to a specific area arcmap




At the View menu, choose Data Frame Options
or  right click map frame, choose 'properties'

click Data Frame tab,

under clip options, choose 'clip to shape',

click specify shape button

choose outline of features

in the layer drop down, choose your clip polygon.

then click apply, ok,