2014-09-27 53 views
1

在票證輸入頁面中,我有一個主要ticketEntry.html頁面,其中包含一行網格和一個用於付款的網格。Kendo UI AngularJs網格指令,undefined

加載ticketEntry.html時,它必須先檢索票據視圖模型(通過對Web API的ajax調用)。直到收到檢票單視圖模型,直線和支付網格才能檢索其數據。

在我目前的解決方案中,我必須在ticketEntry.html的控制器中使用$ timeout才能工作。我正在尋找更乾淨的方式。從ticketEntry.html

提取物:

<div ng-controller="ticketLineController"> 
    <div id="ticketLineGridDiv" kendo-grid="ticketLineGrid" k-options="ticketLineGridOptions"></div> 
</div> 
... 
<div ng-controller="ticketPaymentController"> 
    <div id="ticketPaymentGridDiv" kendo-grid="ticketPaymentGrid" k-options="ticketPaymentGridOptions"></div> 
</div> 

在控制器ticketEntry.html,我有這樣的:

$timeout(function() { 
    ticketService.getTicket(ticketId).then(
     function(ticket) { 
      $scope.initPos(ticket); 
     }, 
     ...); 
}, 500); 

$scope.initPos = function(ticket) { 
    $scope.ticket = ticket; <-- $scope.ticket is used by the line and payment grid 
    $scope.$broadcast('PosReady'); <-- Tell the payment and line controllers to load their grids 
} 

正如你所看到的,我使用$超時延遲500ms,然後我得到票據查看模型並向線路和付款控制器廣播,他們現在可以加載它們的網格。

這是該行控制監聽器:

$scope.$on('PosReady', function (event) { 
    $scope.ticketLineGrid.setDataSource(getGridDataSource()); 
    $scope.ticketLineGrid.dataSource.read(); 
}); 

的問題是,如果我不使用在單輸入控制器$超時,$ scope.ticketLineGrid有時是不確定的位置(同樣的事情付款控制器)。

我一直在使用angular.element(文件)。就緒(而不是在單輸入控制器$超時功能(){...}嘗試過,但沒有處理好這一問題。

如何做$ scope.ticketLineGrid(例如)已被創建的時候/我確定知道嗎?

什麼是處理這種情況的正確方法是什麼?

更新9 /二千〇一十四分之二十七,提供機票上的網格線如何被初始化的更多數據:

在ticketEntry.html的AngularJs指令後,K-options指定爲網格定義對象:

<div id="ticketLineGridDiv" kendo-grid="ticketLineGrid" k-options="ticketLineGridOptions"></div> 

ticketPaymentGridOptions只是與屬性的對象定義網格:

$scope.ticketPaymentGridOptions = { 
    autoBind: false, 
    height: 143, 
    columns: [ 
    { 
     field: "payCode", title: "PayCode", 
    }, 
    { 
     field: "amount", title: "Amount", format: "{0:n2}", attributes: { style: "text-align:right" }, 
    }, 
    ], 
    pageable: false, 
    ... 
}; 

更新2014年9月29日:這是我去的解決方案的基礎上,建議由瓦倫丁

我用兩塊手錶 - 一個在兒童範圍,其中ticketLineGrid生活:

$scope.$watch('ticketLineGrid', function (newVal) { 
    if (angular.isDefined(newVal)) { 
    $scope.ticketControl.lineGridReady = true; 
    } 
}); 

這款手錶設置parent屬性$ scope.ticketControl.lineGridReady = TRUE,一旦電網已初始化。

父(ticketEntryController)的手錶lineGridReady:

$scope.$watch('ticketControl.lineGridReady', function (gridReady) { 
    if (gridReady) { 
    $scope.loadPage(); 
    } 
}); 

$scope.loadPage = function() { 
    ticketService.getTicket(ticketId).then(
    function (ticket) { 
     $scope.initPos(ticket); 
    } 
    ... 
} 

不乾淨,我也喜歡它,但肯定比使用$超時更好...

回答

1

我如何知道何時已經創建/定義了$ scope.ticketLineGrid(例如)?

你可以使用一個$scope.$watch聲明:

$scope.$watch('ticketLineGrid', function (newVal, oldVal) { 
    if(angular.isDefined(newVal)){ 
    // do something with it 
    } 
}) 

然而,在我看來,要做到這一點的好辦法,就是從scope屬性無法檢索數據,但是從promise。我會用只承諾任何事件都爲這個:

var ticketPromise = ticketService.getTicket(ticketId); 

ticketPromise.then(function (ticket) { 
    $scope.ticket = ticket; 
}); 

// you know that part better than I do 
var ticketLineGridPromise = ...; 

$q.all([ticketPromise, ticketLineGridPromise]) 
    .then(function (realizations) { 
    var ticket = realizations[0], ticketLineGrid = realizations[1]; 

    $scope.ticketLineGrid.setDataSource(getGridDataSource()); 
    $scope.ticketLineGrid.dataSource.read(); 
    }) 

,因爲它不是從你的代碼是什麼初始化ticketLineGrid清楚,我無法更精確。

最後,在很多情況下,在您的路由聲明中使用resolve子句非常方便。

+0

我同意一個觀察聲明不是一個好方法。我已經使用諾言來獲得票證視圖模型,然後通過廣播讓子控制器知道何時完成。我已經更新了我的帖子,提供了關於網格如何初始化的數據;它都是聲明式的,並且由劍道網格指令自動處理(使用指定的選項對象)。我當然可以求助於jQuery,並在ticketEntry承諾已經解決(而不是使用廣播)時創建網格,但我更喜歡更加角度的方式。 – Lars335 2014-09-27 23:06:01

+0

廣播或承諾是觸發「事件」的兩種方式;對我來說,承諾的方式似乎更清潔,但爲什麼不呢。但在我看來,你在這裏有一個同步問題,對嗎?您正在等待_both_要加載的票數據和ticketLineGrid準備就緒。這就是爲什麼我建議使用'$ q.all'。 – 2014-09-28 00:25:37

+0

我同意承諾是偉大的,但我如何獲得Kendo UI網格給我一個承諾,讓我知道它什麼時候被初始化? – Lars335 2014-09-28 01:17:03