在故障单入口页面中,我有一个主要的ticketEntry.html页面,其中包含一行网格和一行付款。
加载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
}
正如你所看到的,我使用$ timeout来延迟500ms,然后我得到了票证视图模型,并向线路和支付控制器广播,他们现在可以加载他们的网格。
以下是行控制器中的监听器:
$scope.$on('PosReady', function (event) {
$scope.ticketLineGrid.setDataSource(getGridDataSource());
$scope.ticketLineGrid.dataSource.read();
});
问题是,如果我在票据输入控制器中没有使用$ timeout,那么$ scope.ticketLineGrid有时在这里未定义(与支付控制器相同)。
我尝试在票据输入控制器中使用angular.element(document).ready(function(){...}而不是$ timeout,但是没有处理这个问题。
我如何知道$ scope.ticketLineGrid(例如)何时被创建/定义?
处理此类情景的正确方法是什么?
2014年9月27日更新,以提供有关如何初始化故障单行网格的更多数据:
在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日更新:根据Valentin的建议,这是我的解决方案
我使用两个手表 - 一个在ticketLineGrid所在的子范围内:
$scope.$watch('ticketLineGrid', function (newVal) {
if (angular.isDefined(newVal)) {
$scope.ticketControl.lineGridReady = true;
}
});
一旦网格初始化,此监视器将设置父属性$ 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);
}
...
}
不像我希望的那样干净,但肯定比使用$ timeout ...
更好答案 0 :(得分:1)
我怎么知道$ scope.ticketLineGrid(例如)何时被创建/定义?
您可以使用$scope.$watch
声明:
$scope.$watch('ticketLineGrid', function (newVal, oldVal) {
if(angular.isDefined(newVal)){
// do something with it
}
})
但是,在我看来,这样做的好方法是不是从范围属性中检索数据,而是从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
条款非常方便。