Total Pageviews

2015/03/31

2015/03 Travel


福和河濱公園


馬場町

2015/03/30

[AngularJS] How to format date with ROC's Mínguó calendar System in ng-grid

Problem
I am using AngularJS to implement data grid as bellows:

The first column is date with ROC's Mínguó calendar System.
But the requirement is to format to 104/01/16 as bellows:

The code-snippet for ng-grid is :
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
 $scope.itemGrid = {
    data : 'itemData',
    columnDefs : [
      { field : 'dat', 
        displayName : '轉入日期', 
        width: 350, 
        cellClass: 'text-left'}, 
      { field : 'age', 
        displayName : '機關代號', 
        width: 350, 
        cellClass: 'text-left'}, 
      { field : 'ord', 
        displayName : '收文號  ', 
        width: 350, 
        cellClass: 'text-left'}],
    enableColumnResize :true,
    i18n:'zh-tw',
    multiSelect : false
 };


Solution
Step1. Create a mingGuoFiter to do date format
1
2
3
4
5
 app.filter('mingGuoFilter', function(){
    return function (dat){
      return dat.substring(0, 3) + '/' + dat.substring(3, 5) + '/' + dat.substring(5, 7);
    };
});

Step2. add cellFilter to dat field
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
  $scope.itemGrid = {
    data : 'itemData',
    columnDefs : [
      { field : 'dat', 
        displayName : '轉入日期', 
        width: 350, 
        cellClass: 'text-left',
        cellFilter : 'mingGuoFilter'}, 
      { field : 'age', 
        displayName : '機關代號', 
        width: 350, 
        cellClass: 'text-left'}, 
      { field : 'ord', 
        displayName : '收文號  ', 
        width: 350, 
        cellClass: 'text-left'}],
    enableColumnResize :true,
    i18n:'zh-tw',
    multiSelect : false
 };



2015/03/27

[Git Tool] SourceTree

Requirement
目前專案採用 Git 作為程式碼管理工具,外包廠商的程式交付流程如下

由上圖可以看到,每次開發功能都要 create 一個 branch,完成後 commit上Git,並在GitLab create merge request。經過 review 後,此 branch 才可以 Merge 到 master。

如果我想要看到每次交付的branch,異動到的程式清單,以及每隻程式的異動內容的話,有什麼工具可以輔助達成此需求


Solution
SourceTree 是 Git 的 GUI 工具,讓你不需要用 command line,讓你可以將時間專注於程式開發上。

假設你在電腦中已經有一個 git folder,打開已經安裝好的SourceTree

1. File => Open


2. 指向 folder


3. Click OK


完成以上動作後,在左手邊可以看到現有的branch,假設我點選master,中間的地方就是commit的歷史紀錄



例如目前專案有不同廠商開發,點選某廠商最近commit的branch,中間就是此branch所增加、減少、修改的程式清單,點選某隻程式,右手邊就是該程式所修改的內容。藉此工具可以了解廠商本次commit的branch改了那些程式,動到哪些地方



Reference
[1] http://kenlai.logdown.com/posts/52372--git-dropbox-sourcetree-source-code-management
[2] http://www.sourcetreeapp.com/
[3] http://blog.lyhdev.com/2011/10/sourcetree-git-mercurial-gui-for-mac-os.html
[4] http://www.takobear.tw/201702608526356260322804024687/bear-git-flow-sourcetreegit-flow

2015/03/26

[Eclipse] Open Call hierarchy

I am tracing Java code in Eclipse
Assume it is my tracing Java code hierarchy structure, I may trace from top to down. 

But sometimes, it may be difficult to trace and debug if the call hierarchy has many layers.

DbmAuthorizationServices (class)
   |
   |--doAuthorizeProcess (method)
           |
           |--AuthorizationRepositoryCustomImpl (class)
                 |
                 |--updateAndInsertForIssueAndYByAdmin (method)
                       |
                       |--createDbm130faFromDbm130f1 (method)
                             |
                             |--copyDbm130f1ToDbm130fa (method)



Supposed I had trace to createDbm130faFromDbm130f1 method, I forgot the caller method name
1
2
3
4
5
6
7
8
9
    private Dbm130fa createDbm130faFromDbm130f1(String userId, Date today, Dbm100fa dbm100fa,
            Dbm130fa dbm130fa, Dbm130f1 dbm130f1) {
        copyDbm130f1ToDbm130fa(dbm130f1, userId, today, dbm130fa, Boolean.TRUE,
                dbm100fa.getIssueSeqNo());
        dbm130fa = dbm130faRepository.create(dbm130fa);

        log.debug("[Insert DBM130FA] dbm130fa = " + dbm130fa.toString());
        return dbm130fa;
    }

I can click
ctrl+alt+h or Navigate=>Open Call hierarchy in this method, it will show call hierarchy. Then you can easily to know the hierarchy relationship.




Reference
[1] http://tw-hkt.blogspot.tw/2012/08/eclipse-ide.html
[2] http://mcuoneclipse.com/2012/04/15/10-best-eclipse-shortcuts/

2015/03/20

[Apache POI] HSSFWorkbook and XSSFWorkbook

According to the two posts....
http://albert-myptc.blogspot.tw/2015/03/orgapachepoipoifsfilesystemofficexmlfil.html
http://albert-myptc.blogspot.tw/2015/03/invalidformatexception-package-should.html

If you would like to read xls file, you should utilize HSSFWorkbook. If you misuse it, i.e. upload xlsx file, it will throw exception :  org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)

If you would like to read xlsx file, you should utilize XSSFWorkbook. If you misuse it, i.e. upload xls file, it will throw exception : 
org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]


Hence, if I would like to accept the both, here is my code snippet
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
try {
    // file extension validation
    String extension = StringUtils.upperCase(FilenameUtils.getExtension(fileName));
    if (!("XLS".equals(extension)) && !("XLSX".equals(extension))) {
        String errorMsg = "只接受副檔名為xls與xlsx的檔案, fileName = " + fileName;
        throw new RuntimeException(errorMsg);
    }

    Workbook workbook = null;
    Sheet sheet = null;

    if ("XLS".equals(extension)) {
        // Get the workbook instance for XLS file
        workbook = new HSSFWorkbook(inputStream);
    } else if ("XLSX".equals(extension)) {
        // Get the workbook instance for XLSX file
        workbook = new XSSFWorkbook(inputStream);
    }

    // Get the specific sheet from the workbook
    sheet = workbook.getSheetAt(0);

    Iterator<Row> rowIterator = sheet.iterator();
    while (rowIterator.hasNext()) {
        Row row = rowIterator.next();
        log.debug("row = " + row.getCell(0));
    }

} catch (IOException e) {
    throw e;
}




[Apache POI] org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents

Problem
I have a file upload function, which accept xlsx and xls file.




Here is the code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
     // Get the workbook instance for Excel file
     Workbook workbook = new HSSFWorkbook(inputStream);
     // Get the specific sheet from the workbook
     Sheet sheet = workbook.getSheetAt(0);
     Iterator<Row> rowIterator = sheet.iterator();
     while (rowIterator.hasNext()) {
         Row row = rowIterator.next();
         log.debug("row = " + row.getCell(0));
     }
 } catch (IOException e) {
     throw e;
 }

But as I upload xlsx file, it throw this exception

1
2
3
4
5
6
org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)
 at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:131) ~[poi-3.10-FINAL.jar:3.10-FINAL]
 at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:104) ~[poi-3.10-FINAL.jar:3.10-FINAL]
 at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:128) ~[poi-3.10-FINAL.jar:3.10-FINAL]
 at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:342) ~[poi-3.10-FINAL.jar:3.10-FINAL]
 at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:323) ~[poi-3.10-FINAL.jar:3.10-FINAL]

Solution
To open an xlsx (Office Open XML) file, you should use XSSFWorkbook instead of HSSFWorkbook, which is used for xls (Excel 97-2003) files.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
    // Get the workbook instance for Excel file
    Workbook xslxBook = new XSSFWorkbook(inputStream);
    // Get the specific sheet from the workbook
    Sheet sheet = xslxBook.getSheetAt(0);
    Iterator<Row> rowIterator = sheet.iterator();
    while (rowIterator.hasNext()) {
        Row row = rowIterator.next();
        log.debug("row = " + row.getCell(0).toString());
    }
} catch (IOException e) {
    throw e;
}


Reference

[Apache POI] InvalidFormatException: Package should contain a content type part [M1.13]

Problem
I have a file upload function, which accept xlsx and xls file.


Here is the code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
    // Get the workbook instance for excel file
    Workbook xslxBook = new XSSFWorkbook(inputStream);
    // Get the specific sheet from the workbook
    Sheet sheet = xslxBook.getSheetAt(0);
    Iterator<Row> rowIterator = sheet.iterator();
    while (rowIterator.hasNext()) {
        Row row = rowIterator.next();
        log.debug("row = " + row.getCell(0));
    }
} catch (IOException e) {
    throw e;
}


But as I upload xls file, it throw this exception
1
2
3
 org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]
  at org.apache.poi.util.PackageHelper.open(PackageHelper.java:41) ~[poi-ooxml-3.9.jar:3.9]
  at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:204) ~[poi-ooxml-3.9.jar:3.9]

Solution
The error is telling you that POI couldn't find a core part of the OOXML file. Your file isn't a valid OOXML file, let alone a valid .xlsx file.  So you need to use HSSFWorkbook instead of XSSFWorkbook.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
     // Get the workbook instance for XLS file
     Workbook workbook = new HSSFWorkbook(inputStream);
     // Get the specific sheet from the workbook
     Sheet sheet = workbook.getSheetAt(0);
     Iterator<Row> rowIterator = sheet.iterator();
     while (rowIterator.hasNext()) {
         Row row = rowIterator.next();
         log.debug("row = " + row.getCell(0));
     }
 } catch (IOException e) {
     throw e;
 }



Reference
[1] http://stackoverflow.com/questions/6758364/getting-exceptionorg-apache-poi-openxml4j-exception-no-content-type-m1-13

2015/03/16

資本支出與營運成本

Graham於The Intelligent Investor有提到,資本支出是讓經營者讓企業成長的更大更好的基本工具。會計法允許經營者將營運成本轉換成資本支出,但一些不肖的公司會用此美化公司營收。

所謂的資本支出(Capital expenditure),是指為了獲得固定資產,或為了延長固定資產耐用年限而流出的費用。在會計記賬時,資本支出並不是在支出的當年全部計入費用,而是按照折舊的方式計入每一年的費用。


所謂的營運成本(Operation costs),包括行政開支、分行租金、廣告支出、利息支出、固定資產的折舊等。它們都不是直接成本,不會因為生意收入的増加而立即増加,也不會因為沒有生意收入而免得支出。


公司的毛利 - 營運成本 = 純利


所以,如果把營運成本(Operation costs)轉換成資本支出(Capital expenditure),就可以按折舊的方式來攤提,如此可以美化數字與提升純益


所謂的“資本化”(Capitalization)是指符合條件的相關費用支出不計入當期損益,而是計入相關資產成本,作為資產負債表的資產類專案管理。


簡單地說,資本化就是公司將支出歸類為資產(asset)的方式,因為這樣做對公司長期來說會有好處。費用化,是指此支出對於公司長期來說不具經濟效益,故將其視為費用


Intelligent investor 應該去了解公司的“資本化”(Capitalization)狀況,有那些東西資本化、為什麼資本化。

Reference
[1] http://zh.wikipedia.org/wiki/%E8%B3%87%E6%9C%AC%E6%94%AF%E5%87%BA
[2] http://zh.wikipedia.org/wiki/%E7%87%9F%E9%81%8B%E6%88%90%E6%9C%AC
[3] http://hsmiyu20.pixnet.net/blog/post/251513978-%E6%94%AF%E5%87%BA%E7%9A%84-%E8%B3%87%E6%9C%AC%E5%8C%96-%E8%88%87-%E8%B2%BB%E7%94%A8%E5%8C%96-%3F

2015/03/13

[AngularJS] $scope.$watch

Problem
I have a data grid which implement by ng-grid.
As I click "利率明細", it will pop up a modal dialog and pass parameters into modal dialog. The parameters include "預算別", "債務別", and so on.



預算別 and 債務別 are dynamic and cascading drop down list, it will start to generate these two dynamic and cascading drop down list as it popup modal dialog.


Code snippet in JavaScript (this approach in Line 60 cannot set value correctly, because the dropdown list is dynamic, it set value but the dropdown list is not ready)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//grid definition
$scope.dbm100eFormGrid2 = {
        data : 'dbm100eFormGrid2Data',
        selectedItems: $scope.grid2SelectedRow,
        columnDefs : [
                      { field : 'budgetCode',  displayName : '預算別', 
                        width: 0, cellClass: 'text-left', visible:false},
                      { field : 'diversityAmount',  displayName : '溢(折)價金額', 
                        width: 0, cellClass: 'text-left', visible:false},
                      { field : 'issueCostAmount',  displayName : '發行成本額', 
                        width: 0, cellClass: 'text-left', visible:false},
                      { field : 'budgetName',  displayName : '預算別', 
                        width: 150, cellClass: 'text-left'},
                      { field : 'debtCode',    displayName : '債務別', 
                        width: 0, cellClass: 'text-left'}, 
                      { field : 'debtCodeDesc',    displayName : '債務別', 
                            width: 150, cellClass: 'text-left'}, 
                      { field : 'issueAmount', displayName : '發行額', 
                        width: 180, cellClass: 'text-right', cellFilter: 'number'}, 
                      { field : 'realAmount',  displayName : '實收額', 
                        width: 180, cellClass: 'text-right', cellFilter: 'number'},
                      { field : 'rateDtl',    displayName : '利率%',  
                        width: 170, cellClass: 'text-left',
   //popup modal dialog
                        cellTemplate: '<div class="ngCellText" ng-click="showRateDtl(row);"><a>利率明細</a></div>'}],
        enableColumnResize :true,
        i18n:'zh-tw',
        multiSelect : false
};

$scope.showRateDtl = function(row){
    openDialogForTab2(row);
};

var openDialogForTab2 = function(row){
    var options = {
            templateUrl: 'dbm100eTab4.html',
            controller: ModalInstanceCtrl,
            windowClass: 'app-modal-window',
            backdrop: true,
            keyboard: true,
            backdropClick: true,
            resolve: {
                model: function(){
                    return row.entity;
                }
            }
    };

    var modalInstance = $modal.open(options);
    
    modalInstance.result.then(function (model) {
       // ...
    
};

var ModalInstanceCtrl = function($scope, $modalInstance, model) {
    $scope.dbm100eTab4FormBean = {};
    //set grid data into modal dialog
    $scope.dbm100eTab4FormBean = angular.copy(model);
 //...
};

Solution
Use watch to set value until dropdown lists are ready.
Here is the updated code (check line 59 ~ 64)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//grid definition
$scope.dbm100eFormGrid2 = {
        data : 'dbm100eFormGrid2Data',
        selectedItems: $scope.grid2SelectedRow,
        columnDefs : [
                      { field : 'budgetCode',  displayName : '預算別', 
                        width: 0, cellClass: 'text-left', visible:false},
                      { field : 'diversityAmount',  displayName : '溢(折)價金額', 
                        width: 0, cellClass: 'text-left', visible:false},
                      { field : 'issueCostAmount',  displayName : '發行成本額', 
                        width: 0, cellClass: 'text-left', visible:false},
                      { field : 'budgetName',  displayName : '預算別', 
                        width: 150, cellClass: 'text-left'},
                      { field : 'debtCode',    displayName : '債務別', 
                        width: 0, cellClass: 'text-left'}, 
                      { field : 'debtCodeDesc',    displayName : '債務別', 
                            width: 150, cellClass: 'text-left'}, 
                      { field : 'issueAmount', displayName : '發行額', 
                        width: 180, cellClass: 'text-right', cellFilter: 'number'}, 
                      { field : 'realAmount',  displayName : '實收額', 
                        width: 180, cellClass: 'text-right', cellFilter: 'number'},
                      { field : 'rateDtl',    displayName : '利率%',  
                        width: 170, cellClass: 'text-left',
      //popup modal dialog
                        cellTemplate: '<div class="ngCellText" ng-click="showRateDtl(row);"><a>利率明細</a></div>'}],
        enableColumnResize :true,
        i18n:'zh-tw',
        multiSelect : false
};

$scope.showRateDtl = function(row){
    openDialogForTab2(row);
};

var openDialogForTab2 = function(row){
    var options = {
            templateUrl: 'dbm100eTab4.html',
            controller: ModalInstanceCtrl,
            windowClass: 'app-modal-window',
            backdrop: true,
            keyboard: true,
            backdropClick: true,
            resolve: {
                model: function(){
                    return row.entity;
                }
            }
    };

    var modalInstance = $modal.open(options);
    
    modalInstance.result.then(function (model) {
       // ...
    
};

var ModalInstanceCtrl = function($scope, $modalInstance, model) {
    $scope.dbm100eTab4FormBean = {}; 
    //dbm100eTab4FormBean.debtCode is the name of dropdown list
    //use $scope.$watch means as the dropdown list is ready, then set value
    $scope.$watch("dbm100eTab4FormBean.debtCode", function(newValue, oldValue) {
    //set grid data into modal dialog
        $scope.dbm100eTab4FormBean = angular.copy(model);
    },true);
 //...
};


Reference
[1] http://blog-it.hypoport.de/2013/10/28/angularjs-ordered-init-async-promise/
[2] http://ithelp.ithome.com.tw/question/10139851

2015/03/12

如何計算 Intrinsic Value (股票內在價值)

The Intelligent Investor的作者,有提到一個公式來計算股票的Intrinsic Value內在價值

Intrinsic Value = Current (Normal) Earnings x (8.5 + (2 x Expected Annual Growth Rate)
  • Current (Normal) Earnings = Trailing Twelve Months Earnings Per Share
  • 8.5 = P/E base for a no-growth company
  • Expected Annual Growth Rate = reasonably expected 7 to 10 year growth rate


以下是1210 大成 為例
以下是從2003到2013年這10年的稅後EPS (Column B) 與 EPS成長 (Column C),如C3 = B3 - B4 = 3.42 - 1.43 = 1.99

EPS成長率 = 每年度成長除以上一年度的稅後EPS,如D3 = C4 / B4 = 1.99 / 1.43 = 1.39 X 100 = 139%,過去10年EPS成長率 (Column D) 如下:

過去十年的平均成長 = SUM(C3 : C12) / 10 = 0.49
 Intrinsic Value (股票內在價值) = 最近一年的EPS X (8.5 + 2 X 平均成長率) = B2 X (8.5 + 2 X D14) = 3.42 X (8.5 + 2 X 0.49 ) = 32.42

但是,Graham還是強調,公式所算出的結果僅供參考,因為還有太多的因素會影響到未來的成長率、EPS與股價,如利率的高低會影響到股價,由於股票市場是不保本的,你的投資有可能會賠錢。當利率提高時,投資人就會開始躊躇,在風險與投資報酬的考量下,最後可能會決定把股票部分或全部賣掉,改放到銀行定存,這時候就會造成股價下跌。

Reference
[1] http://www.grahaminvestor.com/articles/how-to/finding-undervalued-stocks-3-using-intrinsic-value/
[2] http://en.wikipedia.org/wiki/Benjamin_Graham_formula
[3] http://goodinfo.tw/stockinfo/StockBzPerformance.asp?STOCK_ID=1210
[4] https://happyeric1120.wordpress.com/2007/06/12/%E5%88%A9%E7%8E%87%E3%80%81%E5%82%B5%E5%88%B8%E3%80%81%E8%88%87%E8%82%A1%E7%A5%A8%E4%B8%89%E8%80%85%E7%9A%84%E9%97%9C%E4%BF%82/

[AngularJS] How to popup modal dialog as I click row in ng-grid

Requirement
I am using ng-grid to implement data grid.
If user click "利率明細" in each row in ng-grid


it should open a modal dialog.

Solution
The code should be like this:  
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 $scope.dbm100eFormGrid2 = {
         data : 'dbm100eFormGrid2Data',
         selectedItems: $scope.grid2SelectedRow,
         columnDefs : [
                       { field : 'budgetCode',  displayName : '預算別', 
                         width: 0, cellClass: 'text-left', visible:false},
                       { field : 'diversityAmount',  displayName : '溢(折)價金額', 
                         width: 0, cellClass: 'text-left', visible:false},
                       { field : 'issueCostAmount',  displayName : '發行成本額', 
                         width: 0, cellClass: 'text-left', visible:false},
                       { field : 'budgetName',  displayName : '預算別', 
                         width: 150, cellClass: 'text-left'},
                       { field : 'debtCode',    displayName : '債務別', 
                         width: 0, cellClass: 'text-left'}, 
                       { field : 'debtName',    displayName : '債務別', 
                             width: 150, cellClass: 'text-left'}, 
                       { field : 'issueAmount', displayName : '發行額', 
                         width: 180, cellClass: 'text-right', cellFilter: 'number'}, 
                       { field : 'realAmount',  displayName : '實收額', 
                         width: 180, cellClass: 'text-right', cellFilter: 'number'},
                       { field : 'rateDtl',    displayName : '利率%',  
                         width: 170, cellClass: 'text-left',
                         cellTemplate: '<div class="ngCellText" ng-click="showRateDtl(row);"><a>利率明細</a></div>'}],
         enableColumnResize :true,
         i18n:'zh-tw',
         multiSelect : false,
         afterSelectionChange: function (row, event) {
             if(!angular.isUndefined($scope.grid2SelectedRow[0])){
                //...
             }
         }
 };
 $scope.showRateDtl = function(row){
     openDialogForTab2(row);
 };
 
 var openDialogForTab2 = function(row){
     var options = {
             templateUrl: 'dbm100eTab4.html',
             controller: ModalInstanceCtrl,
             windowClass: 'app-modal-window',
             backdrop: true,
             keyboard: true,
             backdropClick: true,
             resolve: {
                 model: function(){
                     return row.entity;
                 }
             }
     };

     var modalInstance = $modal.open(options);
     
     modalInstance.result.then(function (model) {
         //...
       });
     
 };
 
 var ModalInstanceCtrl = function($scope, $modalInstance, model) {
     $scope.dbm100eTab4FormBean = angular.copy(model);
     
     //...
     
     $scope.dbm100eFormGrid4 = {
             data : 'dbm100eFormGrid4Data',
             selectedItems: $scope.grid4SelectedRow,
             columnDefs : [
                           { field : 'effcDateB', displayName : '實施日期起', width: 283, cellClass: 'text-left'},
                           { field : 'effcDateE', displayName : '實施日期迄', width: 283, cellClass: 'text-left'},
                           { field : 'debtRate',  displayName : '利率%', width: 283, cellClass: 'text-left'}],
             enableColumnResize :true,
             i18n:'zh-tw',
             multiSelect : false
     };
 };
        

Reference
[1] http://stackoverflow.com/questions/28201723/angular-ui-grid-double-click-row-to-open-pop-up-for-editing-a-row