一尘不染

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

angularjs

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

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

该视图如下所示:

<!-- Pretty standard accordion markup omitted -->
$("#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中看起来不错:

<div id="b2b-line-accordion" class="ui-accordion ui-widget ui-helper-reset" role="tablist"> 
    ... 
</div>

但是其余的标记(与角度进行数据绑定)未启动。

完整标记:

<div id="b2b-line-accordion">
    <div ng-repeat="productCategory in categories">
        <h3>{{ productCategory.CategoryName }}</h3>
        <div class="b2b-line-wrapper">
            <table>
                <tr>
                      <th>Betegnelse</th>
                      <th>Str.</th>
                      <th>Enhed</th>
                      <th>HF varenr.</th>
                      <th>Antal</th>
                      <th>Bemærkninger</th>
                      <th>Beløb</th>
                </tr>
                <tr ng-repeat="product in productCategory.Products">
                    <td>{{ product.ItemGroupName }}</td>
                    <td>{{ product.ItemAttribute }}</td>
                    <td>
                        <select ng-model="product.SelectedVariant"
                                ng-options="variant as variant.VariantUnit for variant in product.Variants"
                                ng-init="product.SelectedVariant = product.Variants[0]"
                                ng-change="calculateLinePrice(product); calculateTotalPrice();">
                        </select>
                    </td>
                    <td>{{ product.ItemNumber }}</td>
                    <td class="line-amount">
                        <span class="ensure-number-label" ng-show="product.IsNumOfSelectedItemsValid">Indtast venligst et tal</span>
                        <input type="number" class="line-amount" name="amount" min="0" ng-change="ensureNumber(product); calculateLinePrice(product); calculateTotalPrice();" ng-model="product.NumOfSelectedItems" value="{{ product.NumOfSelectedItems }}" />
                    <td>
                       <input type="text" name="line-comments" ng-model="product.UserComment" value="{{ product.UserComment }}" /></td>
                    <td><span class="line-sum">{{ product.LinePrice | currency:"" }}</span></td>
                 </tr>
           </table>
   </div>
 </div>
</div>

终于我找到了解决方法!我不确定是不是很漂亮,是否是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准备就绪时,当category数组发生更改时(数据加载后即会执行此操作),我将启动jQuery UI手风琴。

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


阅读 199

收藏
2020-07-04

共1个答案

一尘不染

是的,您需要一个,directive并且您可以处理这种更加棱角分明的方式!

HTML定义指令

<div ui-accordion="accordionData" ></div>

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

在控制器中

$scope.accordionData = myService.getAccordionData();

ui-accordion指令看起来像

.directive('uiAccordion', function($timeout) {
return {
  scope:{
    myAccordionData: '=uiAccordion'
  },
  template: '<div ng-repeat="item in myData"><h3 ng-bind="item.title"></h3><div><p ng-bind="item.data"></p></div></div>',
  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"
        });
       });
     }
   }
  }
})

服务电话成功后,then您就可以创建手风琴了。在这里您可以定义自己的accordion-template喜欢

<div ng-repeat="item in myData">
  <h3 ng-bind="item.title"></h3>
  <div>
     <p ng-bind="item.data"></p>
  </div>
</div>

模板与您的模型数据绑定myData。我ng-repeat在模板内部使用创建accordion-headeraccordion-body
HTML

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

检查 [**Demo**](http://plnkr.co/edit/PPXyIfNnDFCXwfKLRySp?p=preview)

2020-07-04