草庐IT

javascript - 在 AngularJS 服务调用后填充 jQuery UI Accordion

coder 2024-07-14 原文

我目前正在尝试构建一个 AngularJS 应用程序,我正在使用 jQuery UI Accordion 控件。

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

View 看起来像这样:

<!-- Pretty standard accordion markup omitted -->
$("#b2b-line-accordion").togglepanels();

我的 AngularJS Controller 看起来像这样:

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;
    };
});

有什么方法可以让 Accordion “等待”初始化,直到数据从服务返回? :-)

提前致谢!

更新

我尝试链接这些方法并添加了一些日志记录,看起来 Accordion 实际上是在从服务返回 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");
        });
    });

但是,它不显示 Accordion :-( 第一个 Accordion div 在生成的 DOM 中看起来不错:

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

但是标记的其余部分(使用 Angular 进行数据绑定(bind))并未启动。

完整标记:

<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 Accordion 。

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

最佳答案

是的,你需要一个指令,你可以处理这种更 Angular 方式!

HTML中定义指令

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

从您的服务返回promise并将promise传递给指令。

在 Controller 中

$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"
        });
       });
     }
   }
  }
})

当您的服务调用成功时然后您就可以创建 Accordion 了。在这里你可以定义你自己的accordion-template like

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

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

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

检查 Demo

关于javascript - 在 AngularJS 服务调用后填充 jQuery UI Accordion ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21190594/

有关javascript - 在 AngularJS 服务调用后填充 jQuery UI Accordion的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  4. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  5. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  6. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  7. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

  8. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  9. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  10. ruby-on-rails - 在 Rails 中调试生产服务器 - 2

    您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除

随机推荐