Kendo UI AngularJs网格指令,未定义

Kendo UI AngularJs grid directive, undefined

本文关键字:未定义 指令 网格 UI AngularJs Kendo      更新时间:2023-09-26

在票证输入页面中,我有一个主ticketEntry.html页面,其中包含一个行网格和一个付款网格。

加载ticketEntry.html时,必须首先检索ticket视图模型(通过对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选项指定网格的定义对象:

<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,
  ...
};

更新9/29/2014:这是我采用的解决方案,基于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要好。。。

如何知道何时创建/定义了$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子句非常方便。