Total Pageviews

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

No comments: