Day 13 EventCallback, event from child to parent

目前的4篇日志是来自我们写好的假资料,但正常来说不会这样做,而是有颗按钮让使用者按了之後,增加或减少日志的数量。

增加的按钮会放在<Blog>,按了「增加」按钮产生一笔新的Post供使用者输入,再让使用者点击「确认」按钮储存日志。

删除的按钮则可以放在<Blog>,再於<Post>加入checkbox,让使用者自己勾选要删除哪些Post;或是放在<Post>,按下删除按钮就删除该笔日志。

新增按钮很简单,只要在<MyButton>加上@onclick事件即可,开始之前,先将版面稍作修改,顺便把FontSizeStyle移除。
https://ithelp.ithome.com.tw/upload/images/20210913/20140893CVp4F1ZHDT.png

C#部分则加入add()方法,原本loadData()的日志删除。
https://ithelp.ithome.com.tw/upload/images/20210913/20140893bgDJUO9J07.png

接着点击Add按钮,就可以看到日志笔数增加了。
https://ithelp.ithome.com.tw/upload/images/20210913/20140893EAHk5gYd1Q.png

接着来做Delete功能,在Post.razor加入Delete按钮。
https://ithelp.ithome.com.tw/upload/images/20210913/20140893uG4L3oQToH.png

但问题来了,当我按下Delete按钮,<Blog>怎麽知道我删除的是哪一笔Post?这时候就需要PostId可以识别,於是加入一个私有变数postId,每次按下add()都+1,正常来说PostId会跟着Post而不是由Blog产生,不过因为还没接触到资料库,所以先这样将就,未来连接资料库後就会改变。
https://ithelp.ithome.com.tw/upload/images/20210913/20140893IRFOXRAI8w.png

为了验证是否正确,删除原本Post.razor注解的Post.Id,加入新样式的Post.PostId,可以看到没有问题。
https://ithelp.ithome.com.tw/upload/images/20210913/20140893Oz8ro70HYN.pnghttps://ithelp.ithome.com.tw/upload/images/20210913/20140893zDMASGcHrv.png

现在有了识别PostId,又产生了新问题,要怎麽让<Blog>收到PostId?目前PostId由<Blog>产生,所以没这问题,等未来PostId由资料库产生後,<Blog>就不会知道PostId了。前面说的都是从Parent component传递资料到Child component的方法,我们现在要从Child component传资料到Parent component,有办法做到反向传回去吗?

有的,那就是EventCallback,但是要把Delete改成<input>而非<MyButton>,因为EventCallback是由Child传向Parent,如果用<MyButton>,PostId的流向就必须先这样 <Blog>=><Post>=><MyButton>,接着再用EventCallback反向<MyButton>=><Post>=><Blog>,实在太麻烦了。

先把Delete按钮改成<input>,加入@onclick="returnPostId"
https://ithelp.ithome.com.tw/upload/images/20210913/20140893yf7sf58W6T.png

接着在Post.razor.cs定义型别为EventCallback<int>的Property getPostId,记住一定要加上[Parameter]attribute,因为这要让<Blog>呼叫。然後完整定义returnPostId()方法,里面做的就是getPostId.InvokeAsync(Post.PostId);,当外部传来的getPostId被触发时,就将Post.PostId传给Parent也就是<Blog>
https://ithelp.ithome.com.tw/upload/images/20210913/20140893pNF04gyVwb.png

再於Blog.razor.cs定义同名方法getPostId(int id),名字不需要一样,这边只是为了方便取同名,里面做的事情就是移除跟收到的PostId有相同值的Post。
https://ithelp.ithome.com.tw/upload/images/20210913/20140893Pi8BCv8aDl.png

最後在Blog.razor<Post>getPostId放入刚刚定义的方法就可以了。
https://ithelp.ithome.com.tw/upload/images/20210913/20140893ssZP34Vamv.png

我们来实验看看,先新增4笔日志,再删除第2笔,可以看到Post Id等於2的那笔成功被删除了。https://ithelp.ithome.com.tw/upload/images/20210913/201408931xx9cdTwAF.pnghttps://ithelp.ithome.com.tw/upload/images/20210913/201408931QcO0xJanA.png

除了EventCallback,还有Delegate可以使用,不过局限性较大,我们也来试试看。

先在Post.razor.cs定义型别为Action<int>的Property getPostIdForDelegatereturnPostId()改用getPostIdForDelegate
https://ithelp.ithome.com.tw/upload/images/20210913/20140893ZBiVqfeGZK.png

接着在Blog.razor<Post>改用getPostIdForDelegate
https://ithelp.ithome.com.tw/upload/images/20210913/20140893ATOhIyigrb.png

但是真的点击後会发现不会删除日志,这是因为EventCallback会监控Component,一旦有异动就会重新render,Delegate则不会,Delegate必须在Parent component也就是Blog.razor.cs呼叫StateHasChanged();方法,让Parent component知道状态改变了。
https://ithelp.ithome.com.tw/upload/images/20210913/20140893VUpQ1GHnV9.png

另外Delegate一旦在Child component定义了,Parent component就必须要叫用,否则会发生错误,EventCallback则没这问题。
https://ithelp.ithome.com.tw/upload/images/20210913/201408932t4FdnHeWA.png

Ref: Blazor EventCallback

Ref: EventCallback

Ref: Blazor Tutorial - Ep11 - EventCallback and how it is different from delegate


<<:  Day 01:入坑 Angular 的前因後果

>>:  Day 1 为什麽要在云端平台上做数据分析?

最有可能导致数据泄露的针对智能卡(smart cards)的攻击

-侧信道攻击 侧信道攻击(Side-channel attack) 只需在设备或系统附近放置天线、...

Day30 - Windows 提权(1)-Unquoted Service Paths、修改服务提权

假设我们取得受害主机的 shell (cmd.exe 或 powershell)可以根据自己的需求取...

Day.29 其他树的介绍

树有非常多变型,下面是Wiki的截图 以下简单介绍几种常听到的~ AVL Trees、Red Bla...

[番外] 一步一步实现购物车功能 [续]

状态管理 建立一个空间来储存应用程序的 store state store 资料夹 放在 src 下...

Day 5:Hexo 安装完成後的设定密技,并且为 Hexo 换上新布景!

安装好你的 Hexo 部落格後,部落格虽然已经有设定一些预设资料,但要将这些资料改成我们自己的资料嘛...