【问题标题】:Conditionally apply hasDropdown directive on ng-repeated element有条件地对 ng-repeated 元素应用 hasDropdown 指令
【发布时间】:2014-11-02 02:40:32
【问题描述】:

我正在开发一个同时使用 angularJS 和 Foundation 的项目,因此我正在使用 Angular Foundation 项目来让 Foundation 的所有 javascript 部分正常工作。我刚从 0.2.2 升级到 0.3.1,导致 top bar 指令出现问题。

以前,我可以使用 has-dropdown 类来指示其中包含下拉菜单的“顶部栏”菜单项。由于菜单项是从列表中获取的,并且只有一些具有实际的下拉菜单,因此我将使用以下代码:

<li ng-repeat="item in ctrl.items" class="{{item.subItems.length > 0 ? 'has-dropdown' : ''}}">

但是,最新版本需要has-dropdown 的属性而不是类。我尝试了几种解决方案来有条件地包含此属性,但似乎都不起作用:

<li ng-repeat="item in ctrl.items" has-dropdown="{{item.subItems.length > 0}}">

这给了我一个真或假的值,但在这两种情况下,指令实际上都是活动的。使用 ng-attr-has-dropdown 也是如此。

this answer 使用一种有条件地应用一个或另一个元素的方法,一个有指令属性,一个没有指令属性。如果同一个元素是持有ng-repeat 的元素,那将不起作用,所以我想不出任何方法可以使我的代码示例起作用。

this answer我不明白。这适用于我吗?如果是这样,大致如何工作?由于项目的设置,到目前为止我已经编写了几个控制器和服务,但到目前为止我几乎没有任何自定义指令的经验。

简而言之,这可能吗?如何实现?

【问题讨论】:

  • 我认为您必须使用一个指令,根据您的条件返回&lt;li&gt;has-dropdown。我正在寻找答案。我还没有这样做,但这听起来像是我最终会遇到的事情
  • 我找到了这个答案,现在我想为什么它不适合你? jsfiddle.net/gleezer/sCC72/2 它应该可以工作
  • 感谢 Narek,但您并没有真正阅读我的问题。我的问题比这复杂一点。

标签: angularjs zurb-foundation ng-repeat angular-foundation


【解决方案1】:

根据this answer,从 Angular>=1.3 开始,您可以使用 ngAttr 来实现这一点 (docs):

如果插值字符串中的任何表达式导致未定义,则 属性已被移除且未添加到元素中。

所以,例如:

<li ng-repeat="item in ctrl.items" ng-attr-has-dropdown="{{ item.subItems.length > 0 ? true : undefined }}">

angular.module('app', []).controller('testCtrl', ['$scope',
  function ($scope) {
    $scope.ctrl = {
      items: [{
        subItems: [1,2,3,4], name: 'Item 1'
      },{
        subItems: [], name: 'Item 2'
      },{
        subItems: [1,2,3,4], name: 'Item 3'
      }]
    };
  }
]);
<div ng-app="app">
  <ul ng-controller="testCtrl">
    <li ng-repeat="item in ctrl.items" ng-attr-has-dropdown="{{ item.subItems.length > 0 ? true : undefined }}">
      {{item.name}}
    </li>
  </ul>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>

【讨论】:

  • 谢谢,这实际上是一个更好(更规范)的答案,因为它已在 Angular 本身中修复。
【解决方案2】:

好的,我做了一个指令。所有&lt;li&gt; 都需要一个初始属性:

is-drop-down="{{item.subItems.length &gt; 0}}"

然后该指令检查该值并出于某种原因将其作为字符串返回 true。也许有些曾经可以阐明这一点

app.directive('isDropDown', function () {
    return {
        link: function (scope, el, attrs) {
           if (attrs.isDropDown == 'true')
           {
               return el.attr('has-dropdown', true); //true or whatever this value needs to be
           }
       }
    };
});

http://jsfiddle.net/1qyxrcd3/

如果你检查test2,你会看到它有一个has-dropdown 属性。可能有一个更清洁的解决方案,但这就是我所知道的。我还是 Angular 的新手。

编辑我注意到我的示例 json 数据中有几个额外的逗号。请注意,仍然有效,但它们不应该存在。

【讨论】:

  • 这太好了,谢谢!我仍在尝试将它应用到我的应用程序中,但这似乎是朝着正确方向迈出的一大步。我目前收到以下错误(在浏览器控制台中):“错误:[$compile:ctreq] 控制器 'hasDropdown',指令 'topBarDropdown' 需要,找不到!”。我觉得这意味着 hasDropdown 在您的指令生效之前解释页面的某个阶段已经需要。这可能吗?是否可以更改时间以使其及时出现? (该属性在 DOM 中是可见的,所以就是这样)
  • 你把上面的指令放在哪里了?如果你只是复制/粘贴,你必须确保你的 app 变量确实被命名为 app. app.directive 将不起作用,除非您指定了 var app = angular.module('YourApp',[]); 如果它类似于 var myAwesomeApp = angular.module(...),那么指令将是 myAwesomeApp.directive(...)
  • 嘿,我很确定我放置正确,我的应用程序比基本的 1 js 文件设置更大/更复杂,但由于属性确实出现并且控制台日志也显示在正确的时间我相当肯定它在基本层面上起作用。我将尝试移动指令的包含,但我认为它与 Angular-Foundation “topBarDropDown”指令有关,该指令需要存在“hasDropdown”指令。它是但按时间顺序不在正确的订购。
  • 我刚刚意识到我可能问错了问题。我不是有条件地应用属性,而是尝试有条件地应用指令。您的答案是标题中问题的正确答案。
  • 好的,所以属性has-dropdown 会一直存在吗?你能给我一个计算条件与另一个计算条件的例子吗?不确定有条件地应用指令是什么意思。
猜你喜欢
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 2017-01-14
  • 2016-02-27
  • 1970-01-01
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
相关资源
最近更新 更多