使用自定义纯管道与ngIf语句中的布尔值一起时,数据未正确显示。

huangapple go评论62阅读模式
英文:

Data not shown correctly when using custom pure pipe together with boolean in ngIf statement

问题

我正在进行一个网络项目,需要实现友谊/关注功能。我还有两种角色,管理员和(普通)用户。用户可以关注其他用户,而管理员不能关注用户。

用户可以通过点击“关注”按钮来关注另一个用户。如果用户已经关注了一个用户,将显示“取消关注”的选项。使用自定义纯管道,我检查用户是否已经关注了另一个用户。

用户可以看到“关注”或“取消关注”按钮。管理员只能看到一个删除按钮。

以下是管道的代码:

@Pipe({
  name: 'includes',
  pure: true,
})
export class IncludesPipe<T> implements PipeTransform {
  transform(array: T[], item: T): boolean {
    return array.includes(item);
  }
}

以下是在HTML中使用自定义创建的“includes”管道的示例:

<div>
  <table class="table tableborder table-dark">
    <thead>
      <tr>
        <th scope="col">#</th>
        <th scope="col">Voornaam</th>
        <th scope="col">Achternaam</th>
        <th scope="col">Stad</th>
        <th *ngIf="isUser || isAdmin" scope="col"></th>
      </tr>
    </thead>
    <tbody *ngIf="users.length > 0">
      <tr *ngFor="let user of filteredUsers; let i = index">
        <th scope="row">{{ i + 1 }}</th>
        <td>{{ user.firstName | titlecase }}</td>
        <td>{{ user.lastName | titlecase }}</td>
        <td>{{ user.city | titlecase }}</td>
        <div
          *ngIf="currentlyFollowing | includes : user._id; then unfollowTemplate; else followTemplate"
        ></div>
        <ng-template #followTemplate>
          <td>
            <a (click)="followUser(user._id)" class="btn customfriendbutton">Volgen</a>
          </td>
        </ng-template>
        <ng-template #unfollowTemplate>
          <td>
            <a (click)="unfollowUser(user._id)" class="btn customcancelbutton">Ontvolgen</a>
          </td>
        </ng-template>
        <td *ngIf="isAdmin">
          <a (click)="sweetAlertDeleteConfirmation(user._id)" class="btn customdeletebutton">Verwijderen</a>
        </td>
      </tr>
    </tbody>
    <tbody *ngIf="users.length === 0">
      <td colspan="5">
        <h2 class="text-center">Er zijn geen leden gevonden!</h2>
      </td>
    </tbody>
  </table>
</div>

我使用一个布尔值“isUser”来跟踪当前登录用户的角色。这在没有添加额外表达式到ngIf语句时正常工作,例如:

<div *ngIf="isUser && currentlyFollowing | includes : user._id; then unfollowTemplate; else followTemplate"></div>

但是,当以管理员帐户登录时,即“isUser”等于false时,数据加载不正确。第一张图片显示正确的数据,第二张图片显示缺少的数据。您可以看到一些数据行缺失,删除按钮不会在每一行中显示。

我不明白为什么在ngIf语句中添加“isUser”后,数据不会正确加载。我预期不会显示ng模板的任何一个,而“删除”按钮将显示在每一行中。某种方式,“isUser”在ngIf中破坏了它。

在控制台中,您得到的错误如下:

移除ngIf语句中的布尔值“isUser”解决了我的问题。但我想知道为什么,以便更好地理解。

英文:

I am doing a webproject where i need friendship/follow functionality. I also have two roles admins and (regular) users. Users can follow other users. Admins can not follow users.

A user can follow another user by clicking on a Follow ("Volgen)" button. If the user already follows an user an unfollow ("ontvolgen") will be shown. With the use of a custom pure pipe i check wether the user already follows a user.

A users sees either the follow or unfollow button. An admin is only able to see a delete button.

This is the code of the pipe:

@Pipe({
name: &#39;includes&#39;,
pure: true,
})
export class IncludesPipe&lt;T&gt; implements PipeTransform {
transform(array: T[], item: T): boolean {
return array.includes(item);
}
}

This is the use of the custom created 'includes' pipe in html:

&lt;div
&lt;table class=&quot;table tableborder table-dark&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope=&quot;col&quot;&gt;#&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Voornaam&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Achternaam&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Stad&lt;/th&gt;
&lt;th *ngIf=&quot;isUser || isAdmin&quot; scope=&quot;col&quot;&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody *ngIf=&quot;users.length &gt; 0&quot;&gt;
&lt;tr *ngFor=&quot;let user of filteredUsers; let i = index&quot;&gt;
&lt;th scope=&quot;row&quot;&gt;{{ i + 1 }}&lt;/th&gt;
&lt;td&gt;{{ user.firstName | titlecase }}&lt;/td&gt;
&lt;td&gt;{{ user.lastName | titlecase }}&lt;/td&gt;
&lt;td&gt;{{ user.city | titlecase }}&lt;/td&gt;
&lt;div
*ngIf=&quot;
currentlyFollowing | includes : user._id;
then unfollowTemplate;
else followTemplate
&quot;
&gt;&lt;/div&gt;
&lt;ng-template #followTemplate&gt;
&lt;td&gt;
&lt;a
(click)=&quot;followUser(user._id)&quot;
class=&quot;btn customfriendbutton&quot;
&gt;Volgen&lt;/a
&gt;
&lt;/td&gt;
&lt;/ng-template&gt;
&lt;ng-template #unfollowTemplate&gt;
&lt;td&gt;
&lt;a
(click)=&quot;unfollowUser(user._id)&quot;
class=&quot;btn customcancelbutton&quot;
&gt;Ontvolgen&lt;/a
&gt;
&lt;/td&gt;
&lt;/ng-template&gt;
&lt;td *ngIf=&quot;isAdmin&quot;&gt;
&lt;a
(click)=&quot;sweetAlertDeleteConfirmation(user._id)&quot;
class=&quot;btn customdeletebutton&quot;
&gt;
Verwijderen
&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody *ngIf=&quot;users.length === 0&quot;&gt;
&lt;td colspan=&quot;5&quot;&gt;
&lt;h2 class=&quot;text-center&quot;&gt;Er zijn geen leden gevonden!&lt;/h2&gt;
&lt;/td&gt;
&lt;/tbody&gt;
&lt;/table&gt;

I keep track of the role of the current logged in user with a boolean: "isUser".
This works perfectly untill i add another expression in ngIf statement where the pipe is located like so:

              &lt;div
*ngIf=&quot;
isUser &amp;&amp; currentlyFollowing | includes : user._id;
then unfollowTemplate;
else followTemplate
&quot;
&gt;&lt;/div&gt;

When im logged in with an admin account and thus isUser equals false, the data is not loaded correctly.
first images shows correct data: Correct data
Second images shows missing data: Incorrect data

as you can see some rows of data are missing and the delete button wont show in every row.

I do not understand why the data does not load correctly when isUser is added to the ngIf statement. I expect that neither of the ng templates are shown and the "verwijderen" (delete) button will be shown in every row. Somehow the isUser in ngIf breaks it.

This is the error i get in the console: error in console

Removing the boolean isUser from the ngIf statement fixed my problem. But i want to know why so i get a beter understanding.

答案1

得分: 1

你期望这段代码如何工作:

(isUser) && (currentlyFollowing | includes : user._id)

实际上你写的代码是这样的:

(isUser && currentlyFollowing) | includes : user._id

所以当 isUser 为 false 时,你的 `includes` 管道会接收到一个布尔值 `false`:

true && [1,2,3] => [1,2,3]
false && [1,2,3] => false

要修复这个问题 - 添加一些 `(` 和 `)`:

&lt;div
  *ngIf=&quot;
    isUser && (currentlyFollowing | includes : user._id);
    then unfollowTemplate;
    else followTemplate
  &quot;
&gt;&lt;/div&gt;
英文:

How you expect this code to work:

(isUser) &amp;&amp; (currentlyFollowing | includes : user._id)

How it actually works as per how you wrote it:

(isUser &amp;&amp; currentlyFollowing) | includes : user._id

So your includes pipe receives a boolean false value when isUser is false:

true &amp;&amp; [1,2,3] =&gt; [1,2,3]
false &amp;&amp; [1,2,3] =&gt; false

To fix - add some ( and ):

&lt;div
*ngIf=&quot;
isUser &amp;&amp; (currentlyFollowing | includes : user._id);
then unfollowTemplate;
else followTemplate
&quot;
&gt;&lt;/div&gt;

使用自定义纯管道与ngIf语句中的布尔值一起时,数据未正确显示。

(note: reload build-in browser on sandbox manually, it acts a bit buggy)

答案2

得分: 0

我假设语句 isUser && currentlyFollowing 首先被计算,得到一个布尔值。然后这个布尔值被传递到你的 includes 管道中,因此出现了 array.includes is not a function 错误。

我建议你通过检查管道内部得到的类型(数值)来开始调试。

如果是这种情况,可以使用括号来覆盖运算符优先级,如: isUser && (currentlyFollowing | includes : user._id)

英文:

I assume statement isUser &amp;&amp; currentlyFollowing is computed first, which results in boolean. Then this boolean value gets passed into your includes pipe, hence your array.includes is not a function error.

I'd suggest you to start debugging by checking what type (value) you get inside the pipe.

If that's the case, use parentheses to override operator precedence like: isUser &amp;&amp; (currentlyFollowing | includes : user._id).

huangapple
  • 本文由 发表于 2023年2月6日 04:52:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75355429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定