【发布时间】:2014-01-17 16:14:13
【问题描述】:
我目前正在尝试构建一个使用 jQuery UI 手风琴控件的 AngularJS 应用程序。
问题是,jQuery UI 手风琴是在 我的 AngularJS 服务完成从服务器加载数据之前启动的。换句话说:手风琴在启动时没有任何数据,因此在填充来自 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 准备好并且类别数组发生变化时(它在加载数据时发生),我正在启动 jQuery UI 手风琴。
非常感谢@Sgoldy 为我指明了正确的方向!
【问题讨论】:
-
你查看过 Angular 的 jQuery UI adapter 吗?我使用了另一组为jQuery Mobile 制作的一个,它提供了一个角度指令并且效果很好。我看到您找到了解决方案,但这可能会更好地遵循角度约定。
标签: javascript jquery jquery-ui angularjs