ngНе обновлять вид, если только не нажать на вид Angular - PullRequest
0 голосов
/ 01 октября 2019

Я пытался также обнаружить, что такое: (), marforCheck (), переназначить, но ничего не изменилось. Они просто меняются после того, как я снова нажму на вид. Сценарий: я получаю данные из магазина, я успешно отслеживал изменение данных в функции подписки.

    this.allInfo$.subscribe(data => {
      this.allInfos = data;
    });
 <div (click)="addInfo(social)" *ngFor="let info of allInfos"
         [ngClass]="{'active': info.connected}">
        <span>{{info.name}} {{info.connected}}</span>
      </div>

Когда я нажимаю addInfo, приложение открывает стороннее диалоговое окно, такое как вход в систему через firebase, если в случае успеха вернутся новые данные и обновятся до отслеживаемой информации allInfo $ I. Но мнение не меняется? Это угловая ошибка? Просмотреть изменения, если я нажму где-нибудь на экране Моя угловая версия 7

ОБНОВЛЕНО: Моя проблема была решена с помощью _ngZone.run ()

Ответы [ 3 ]

0 голосов
/ 01 октября 2019

trackBy

   <div (click)="addInfo(social)" *ngFor="let info of allInfos;trackBy:trackByFunction"
             [ngClass]="{'active': info.connected}">
            <span>{{info.name}} {{info.connected}}</span>
    </div>

.ts

trackByFunction(index, info){
if(!info)return null;
return info.id; //or return index;
}

Ссылка: - https://medium.com/better-programming/improving-angular-ngfor-performance-through-trackby-ae4cf943b878

0 голосов
/ 01 октября 2019

подписка не помещает "слушателя" в базу данных, поэтому любое изменение в базе данных является рефлекторным. Каждое изменение в dbs нужно либо получить список заново, либо добавить вручную в свой массив allInfos.

Вы говорите: «Когда я нажму на addInfo, приложение откроет стороннее диалоговое окно, такое как вход в систему через firebase, если в случае успеха вернутся новые данные и обновятся до allInfo $»

Я понятия не имею о вашем addInfo, поэтомуЯ полагаю, что ваш addInfo похож на

addInfo(data)
{
    this.service.addData(data).subscribe(res=>{
       console.log(res) //generally success
    })
}

Вы можете, например,

addInfo(data)
{
    this.service.addData(data).subscribe(res=>{
       if (sucess)
         this.allInfos.push(data)
    })
}

или addInfo (data) {this.service.addData (data) .pipe (switchMap (res =)> {return res.success? this.allInfo $: of (null)})) .subscribe (res => {if (res) this.allInfos = res})}

Возможно, что "третья сторона"диалог сделать рядом с вашим $ allInfo ", (чем все это ненужно), но я не знаю. Представьте, что у вас есть типичная служба CRUD, такая как

@Injectable()
export class ProductService {
  endpoint: string = '[YOUR_DB_SERVER_IP]';

  constructor(
    private http: HttpClient
  ) {}

  // CREATE
  createProduct(productToCreate: IProduct): Observable<IProduct[]> {
    return this.http.post(`${this.endpoint}/products`, productToCreate);
  }

  // READ
  readProducts(): Observable<IProduct[]> {
    return this.http.get(`${this.endpoint}/products`);
  }

  // UPDATE
  updateProduct(objToUpdate: IProduct): Observable<IProduct[]> {
    return this.http.patch(`${this.endpoint}/products/${objToUpdate.id}`, objToUpdate};
  }

  // DELETE 
  deleteProduct(): Observable<IProduct[]> {
    return this.http.delete(`${this.endpoint}/products/${objToDelete.id}`);
  }
}

Мы меняемся так, каждое изменение генерирует событие

  private dbsChangeSubject = new Subject<any>();
  dbsChange = this.dbsChangeSubject .asObservable();

  // CREATE
  createProduct(productToCreate: IProduct): Observable<IProduct[]> {
    return this.http.post(`${this.endpoint}/products`, productToCreate).pipe(
        tap(result=>{
          if (result.success)
             this.dbsChangeSubject.next(true)
        }))
    );
  }

  // UPDATE
  updateProduct(objToUpdate: IProduct): Observable<IProduct[]> {
    return this.http.patch(`${this.endpoint}/products/${objToUpdate.id}`, objToUpdate.pipe(
        tap(result=>{
          if (result.success)
             this.dbsChangeSubject.next(true)
        }))
    );;
  }

  // DELETE 
  deleteProduct(): Observable<IProduct[]> {
    return this.http.delete(`${this.endpoint}/products/${objToDelete.id}`).pipe(
        tap(result=>{
          if (result.success)
             this.dbsChangeSubject.next(true)
        }))
    );
  }
}

Знайте, что мы можем подписаться на

this.service.dbsChange().pipe(
startWith(true),
switchMap(()=>{
    this.service.readProducts()
})).subscribe(res=>{
   this.products=res
})

Здесь мы подписываемся на "dbsChange", а не на readProducts (), поэтому мы слушаем все this.dbsChangeSubject.next, который у нас есть

0 голосов
/ 01 октября 2019

Вы сохранили событие click для, поэтому, когда вы нажимаете на этот div, оно обновляется.

<div  *ngFor="let info of allInfos"
         [ngClass]="{'active': info.connected}">
        <span (click)="addInfo(social)">{{info.name}} {{info.connected}}</span>
</div>

в этом коде представление будет обновляться при нажатии на промежуток

...