动态创建的变量没有作用域?

时间:2018-12-20 15:27:23

标签: angular

因此,以前在Angular 1.X中,我已经习惯了在html端创建局部变量。

通常看起来像这样(AngularJS):

<div class="parentContainer" ng-repeat="error in $ctrl.systemErrorMessages>
    <div ng-click="showHide=(showHide ? false : true)">
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        Click me to toggle all selectors in the same hierarchical-level (scope) as me.
    </div>

    <div ng-if="showHide"> {{error.message}} </div>
</div>

上面的代码将创建变量并在其中显示div。

但是,如果我在Angular 1.X中将其放在ng-repeat标记内,则该变量将在其作用域内是局部的。可以说systemErrMessages中有50个条目,当我现在单击toggle-div时,所有50个条目都在起作用……过去是这样-仅单击了单击whos toggle-div的消息;反应了...

似乎Angular2打破了ngFor的范围,并影响了 ALL 元素。

我要尝试的内容(角度2):

<div *ngFor="let error of systemErrMessages">
     <div class="item" [hidden]="showHide">
        ErrorMessage: {{error}}
     </div>
     <div (click)="showHide=(showHide ? false : true)">TOGGLE above</div>
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
</div>

要澄清(TL; DR):

HTML结构(ngFor生成的内容):

<div class="parentContainer">
    <div class="item">
        <div class="information" [hidden]="showHide">lorem ipsum</div>
        <div (click)="showHide=(showHide ? false : true)">TOGGLE</div>
    </div>
    <div class="item">...</div>
    <div class="item">...</div>
    <div class="item">...</div>
    <div class="item">...</div>
    <div class="item">...</div>
    <div class="item">...</div>
</div>

当我单击angular2中的TOGGLE时,会显示 ALL 元素。

仅在AngularJS中 .item的{​​{1}}是可见的。

是否可以获得与1.X相同的行为?

3 个答案:

答案 0 :(得分:2)

Angular ^ 7.x.x

如果要在模板中创建动态变量,则只需创建它即可:

<div *ngFor="let error of systemErrMessages; let showHide = 'showHide'">
                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
     <div class="item" [hidden]="showHide">
        ErrorMessage: {{error}}
     </div>
     <div (click)="showHide = !showHide">TOGGLE above</div>
</div>

否则,您的showHide变量将具有组件范围。

答案 1 :(得分:-1)

  

看来Angular2打破了ngFor的范围,并影响了所有元素。

一切都是基于组件的,没有像angularjs那样的Scope(全局,隐式或其他)。在HTML中引用实例时,假定它们植根于与模板关联的组件中。

  

是否可能获得与1.X相同的行为?

不。您必须明确定义跟踪状态的位置(在这种情况下),因为在angular2 +中,作用域已不再重要。

使用您发布的代码,将其更改为与“ angular2 +兼容”的最简单方法是跟踪数组中该项的可见性。在这种情况下,将字符串数组扩展为包含该字符串以及是否应该可见的对象的数组。

请参见stackblitz

app.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
  systemErrMessages: {error: string, hidden: boolean}[];

  ngOnInit(){
    // ['one','two','three'] could be any source
    this.systemErrMessages = ['one','two','three'].map(_ => {
      return {error: _, hidden: true};
    });

    this.systemErrMessages.push({error: 'any other error', hidden: false});
  }
}

app.component.html

<div *ngFor="let error of systemErrMessages">
     <div class="item" [hidden]="error.hidden">
        ErrorMessage: {{error.error}}
     </div>
     <button (click)="error.hidden = !error.hidden">Toggle</button>
</div>

答案 2 :(得分:-1)

Joel,在Angular中,变量也是动态创建的,但始终相同。就像您在.ts中声明变量showHide。同样,同一变量会影响所有div。解决方案是使用多个变量-每个div一个

如果像Igor所说的那样遍历对象数组,就可以

<button (click)="error.hidden = !error.hidden">Toggle</button>

如果要遍历字符串数组,则需要声明一个检查数组,然后使用索引。那是

<!--take a look to ";let i=index"-->
<div *ngFor="let error of systemErrMessages;let i=index">
     <div (click)="showHide[i]=(showHide[i] ? false : true)">TOGGLE above</div>
</div>

//And in your .ts don't forget declare
showHide:boolean[]=[]