【问题标题】:First ng-repeat boolean true, rest false第一个 ng-repeat 布尔值 true,其余为 false
【发布时间】:2018-01-03 01:45:10
【问题描述】:

我正在使用 Angular 1.5。我有一个带有 ng-repeat 的 li 元素:

<li ng-repeat="contract in vm.contracts.items" contract="contract" change-payment-method-active="vm.changePaymentMethodSssIsActive">
    <contract-timeline-item></contract-timeline-item>
</li>

li 元素内部是一个contract-timeline-item 组件。

每个contract-timeline-item 组件他的这个html:

<div id="toggleContract"><button ng-click="vm.toggleContract()">Toggle contract</button></div>
<div class="uc-card-datablock" ng-if="vm.toggle">

还有这段代码:

private toggle: boolean = false;

public toggleContract() {
    this.toggle = (this.toggle === true) ? false : true;
}

当用户打开页面时,所有合约的切换布尔值为 false,用户可以单击切换按钮来打开/关闭它们。

但我希望第一个合同的切换值是 true,以便用户可以看到它。

我可以通过向合约模型添加一个toggleStatus 值来解决这个问题,在父容器中我可以获取合约数组的第一个合约项并将toggleStatus 设置为true。但我希望在不更改模型和添加不属于该模型的属性的情况下做到这一点。

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    为了在您需要以应有的方式使用组件之后实现您的目标,即通过绑定传递数据。您将传递您的合同数据以及标志来告诉您处理的天气contract-timeline-item这是第一个还是不是。

    它看起来像这样:

    class contractTimelineItem {
        private toggle: boolean = false;
    
        $onInit() {
          this.toggle = this.expanded;
        }
    
        public toggleContract() {
          this.toggle = !this.toggle;
        }    
      }
    

    此组件的绑定如下所示:

    bindings: {
      contract: '=',
      expanded: '<'
    },
    

    那么 HTML 部分需要是这样的:

    <li ng-repeat="contract in vm.contracts.items" contract="contract" change-payment-method-active="vm.changePaymentMethodSssIsActive">
      <contract-timeline-item 
        expanded="$first"
        contract="contract"
      ></contract-timeline-item>
    </li>
    

    这是一个演示http://plnkr.co/edit/9v8xdl7YR4oBYt3Bjgf3?p=preview

    【讨论】:

    • 干杯!就是在看这个。这在 Angular 2 中更容易工作,但现在我被困在 1.5 中。
    • 我必须将private expanded: boolean; 添加到我的班级,否则我会收到TS2339: Property 'expanded' does not exist on type 错误。
    【解决方案2】:

    您可以在 ng-if 中使用 $index 将第一项的切换设置为 true

    <div class="uc-card-datablock" ng-if="vm.toggle || $index == 0">
    

    【讨论】:

    • 嗯,这只适用于 ng-repeat 项目。我想我应该改写我的问题。每个contract-timeline-item 都有一个布尔toggleValue(布尔值)。并且它们被设置为假,只有第一个应该是真的。因此,与其说是显示/隐藏,不如说是向子组件传递一个值。
    【解决方案3】:

    由于你有单独的指令范围,你必须传递哪个元素是第一个,你可以这样做

    <li ng-repeat="contract in vm.contracts.items" contract="contract" change-payment-method-active="vm.changePaymentMethodSssIsActive">
        <contract-timeline-item is-first="$first"></contract-timeline-item>
    </li>
    

    现在要在您的范围代码中使用它,请执行此操作 -

    private toggle: boolean = attr.isFirst;
    
    public toggleContract() {
        this.toggle = !this.toggle;
    }
    

    【讨论】:

    • 您的想法是正确的,但这是行不通的。另外它会抛出语法错误。
    • attr.is-first 仅对第一个元素为真,其余元素为假,因此切换布尔值设置正确,然后在 toggleContract 上,您只需设置相反的值。我不明白为什么它不起作用?
    • 你认为attr 会来自哪里? ReferenceError 将被抛出,因为您在使用之前没有定义变量 first
    • attr 在该指令的链接函数中作为参数传递,返回{link: function(scope, element, attr) { //此处的指令作用域代码}}。我想如果一个人做了一个指令,那么他对使用可以传递给指令的属性有基本的了解
    • 当然,但是在 OP 案例中没有链接功能和指令 :) 尝试使用您的代码创建一个演示(不要忘记打字稿),您会明白我的意思。
    【解决方案4】:

    您可以在 ng-repeat 中使用 $first。如果它是循环中的第一个元素,将其作为组件的参数添加,则该值将为真。

    <li ng-repeat="contract in vm.contracts.items" contract="contract" change-payment-method-active="vm.changePaymentMethodSssIsActive">
    <contract-timeline-item toggle='$first'></contract-timeline-item>
    

    【讨论】:

    • 我应该如何处理canBeToggled
    • 就叫它“切换”吧,我的错。我将编辑我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-17
    • 2017-10-30
    • 2015-09-06
    相关资源
    最近更新 更多