在AngularJS服务调用之后填充jQuery UI手风琴

我正在尝试构建一个AngularJS应用程序,我正在使用jQuery UI手风琴控件。

问题是,jQuery UI手风琴是我的AngularJS服务从服务器加载数据之前启动的。 换句话说:手风琴在启动时没有任何数据,因此不会显示何时填充AngularJS的数据。

该视图如下所示:

 $("#b2b-line-accordion").togglepanels(); 

我的AngularJS控制器看起来像这样:

 app.controller('orderController', function ($scope, orderService, userService) { // Constructor for this controller init(); function init() { $scope.selected = {}; $scope.totalSum = 0.00; $scope.shippingDate = ""; $scope.selectedShippingAddress = ""; $scope.orderComment = ""; $scope.agreements = false; $scope.passwordResetSuccess = false; $scope.passwordResetError = true; userService.getCurrentUser(2).then(function (response) { $scope.user = response.data; orderService.getProductCategoriesWithProducts($scope.user).then(function (d) { $scope.categories = d.data; }); }); } // Other methods omitted }); 

我的AngularJS服务看起来像这样:

 app.service('orderService', function ($http) { this.getProductCategoriesWithProducts = function (user) { return $http.post('url to my service', user); }; }); app.service('userService', function ($http) { this.getCurrentUser = function(companyId) { return $http.get('url to my service' + companyId + '.aspx'); }; this.resetPassword = function() { return true; }; }); 

有没有办法告诉手风琴“等待”初始化,直到从服务返回数据? 🙂

提前致谢!

更新

我尝试链接方法并添加一些日志记录,似乎手风琴实际上是在从服务返回JSON之后启动的。

  userService.getCurrentUser(2).then(function(response) { $scope.user = response.data; }).then(function() { orderService.getProductCategoriesWithProducts($scope.user).then(function(d) { $scope.categories = d.data; console.log("categories loaded"); }).then(function () { $("#b2b-line-accordion").accordion(); console.log("accordion loaded"); }); }); 

但是,它不显示手风琴:-(第一个手风琴div在生成的DOM中看起来很好:

 
...

但其余的标记(用角度数据绑定)并未启动。

完整标记:

 

{{ productCategory.CategoryName }}

Betegnelse Str. Enhed HF varenr. Antal Bemærkninger Beløb
{{ product.ItemGroupName }} {{ product.ItemAttribute }} {{ product.ItemNumber }} Indtast venligst et tal {{ product.LinePrice | currency:"" }}

最后我找到了解决这个问题的方法! 我不完全确定它是否漂亮,如果它是Angular方式的东西(我猜它不是)

使用以下代码制定指令:

 app.directive('accordion', function () { return { restrict: 'A', link: function ($scope, $element, attrs) { $(document).ready(function () { $scope.$watch('categories', function () { if ($scope.categories != null) { $element.accordion(); } }); }); } }; }); 

所以基本上当DOM准备就绪并且类别数组发生变化时(在数据加载时它会发生变化),我正在启动jQuery UI手风琴。

非常感谢@Sgoldy指点我这里正确的方向!

是的,你需要一个directive ,你可以处理这种更有棱角的方式!

HTML定义指令

 

从您的service退回promise并将promise传递给指令。

在控制器中

 $scope.accordionData = myService.getAccordionData(); 

ui-accordion指令看起来像

 .directive('uiAccordion', function($timeout) { return { scope:{ myAccordionData: '=uiAccordion' }, template: '

', link: function(scope, element) { scope.myAccordionData.then(function(data) { scope.myData = data; generateAccordion(); }); var generateAccordion = function() { $timeout(function() { //<--- used $timeout to make sure ng-repeat is REALLY finished $(element).accordion({ header: "> div > h3" }); }); } } } })

当您的服务呼叫成功时,您将创建您的手风琴。 在这里你可以定义自己的accordion-template

 

模板与模型数据myData绑定。 我在模板中使用ng-repeat来创建accordion-headeraccordion-body HTML

generateAccordion方法中,我使用$timeout来确保ng-repeat真正完成渲染,因为$timeout将在当前摘要周期结束时执行。

检查演示

我的最佳实践是在启动控制器之前解决异步服务。

正如您在文档中看到的那样, http: //docs.angularjs.org/api/ngRoute。$ routeProvider

resolve – {Object。=} – 应该注入控制器的可选依赖关系映射。 如果这些依赖项中的任何一个是promise,路由器将等待它们全部被解析或者在实例化控制器之前被拒绝。 如果成功解析了所有promise,则会注入已解析的promise的值,并触发$ routeChangeSuccess事件。 如果任何promise被拒绝,则触发$ routeChangeError事件。

在解决或拒绝服务之前,您的控制器和视图甚至不会启动。

有一个很好的video教程, https://egghead.io/lessons/angularjs-resolve

在您的情况下,您可以配置如下所示的路由

 var myApp = angular.module('myApp', ['ngRoute']); myApp.config(function($routeProvider) { $routeProvider.when('/', { templateUrl: 'main.html', controller: orderController, resolve: { categories: function(orderService) { return orderService.getProductCategoriesWithProducts(); }, user: function(userService) { return userService.getCurrentUser(); } } }); 

然后,与您的控制器

 app.controller('orderController', function($scope, categories, user) { //categories and user is always here, so use it. }); 

我也在这里找到了类似的问题和答案