Asp.Net Core入門之靜態文件

靜態文件(css,js,html等類型文件)通常位於 web根目錄下,而ASP.Net Core框架默認內容根目錄下的wwwroot文件夾為web根目錄。這裏簡單解釋下內容根目錄:實際就是指包含可執行程序exe,程序集dll,配置文件json,xml等的文件目錄.

1.訪問web根目錄靜態文件

正常情況下,靜態文件是無法直接訪問的,需要我們添加如下靜態文件的中間件,這是框架內置自帶的。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseStaticFiles(); 
}

然後我們就可通過web根目錄的相關路徑訪問靜態文件。例如,Web 應用程序項目模板包含 wwwroot 文件夾中的多個文件夾 :

  • wwwroot
    • css
    • images
    • js

然後就可以通過如下格式的URL:https://localhost:5001/images/123.jpg 來訪問靜態文件。

2.訪問web根目錄之外的靜態文件

有些時候,可能有些靜態文件我們並不是放在web根目錄下面的。例如如下一個目錄層次結構,其中要提供的靜態文件位於 Web 根目錄之外:

  • wwwroot
    • css
    • images
    • js
  • Content
    • images
      • img.jpg

如果通過URL:https://localhost:5001/Content/images/img.jpg是無法訪問的,這個時候我們就需要額外的指定靜態文件路徑:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
           //wwroot目錄下靜態文件
 app.UseStaticFiles(); //wwwroot之外的靜態文件 app.UseStaticFiles(new StaticFileOptions { //指定實際物理路徑 FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"Content/images")), //設置URL請求的文件路徑 RequestPath = new Microsoft.AspNetCore.Http.PathString("/MyStaticFiles") }); }

然後就可以通過如下格式的URL:https://localhost:5001/MyStaticFiles/img.jpg 來訪問靜態文件。

3.提供默認文件

UseDefaultFiles中間件用於啟用默認文件的功能,例如我們打開一個網站只輸入網站地址,就會自動跳出網站首頁。這裏的網站首頁實際就相當於一個默認文件。

ASP.Net Core為我們簡化了默認文件的搜索功能,我們只需要添加中間件即可。

public void Configure(IApplicationBuilder app)
{
    app.UseDefaultFiles();
    app.UseStaticFiles();
}

要提供默認文件,必須在 UseStaticFiles 前調用 UseDefaultFiles。 UseDefaultFiles 實際上用於重寫 URL,不提供文件。 通過 UseStaticFiles 啟用靜態文件中間件來提供文件。

 UseDefaultFiles 默認支持以下幾種類型文件:

  • default.htm
  • default.html
  • index.htm
  • index.html

當然,框架也支持自定義默認文件,感興趣的同學可以研究一下。

例如如下一個目錄層次結構:

  • wwwroot
    • Index.html
    • css
    • images
    • js
  • 通過URL:https://localhost:5001/訪問時,會自動跳轉到並打開Index.html頁面

4.啟用目錄瀏覽功能

出於安全考慮,目錄瀏覽默認處於禁用狀態,需通過添加UseDirectoryBrowser中間件的方式開啟。

public void Configure(IApplicationBuilder app)
{
    //默認文件
 app.UseDefaultFiles(); //靜態文件  app.UseStaticFiles(); //目錄瀏覽  app.UseDirectoryBrowser(); }

另外,需要註冊目錄瀏覽的服務

public void ConfigureServices(IServiceCollection services)
{
    services.AddDirectoryBrowser();
}

例如如下一個目錄層次結構:

   wwwroot

  • 123.jpg
  • 234.jpg

通過URL:https://localhost:5001/訪問時,由於wwwroot根目錄下不存在默認文件,所以會打開文件目錄。

 

 5.UseFileServer

UseFileServer 結合了 UseStaticFilesUseDefaultFiles 和 UseDirectoryBrowser(可選)的功能。

例如以下目錄層次結構:

  • wwwroot
    • 123.jpg
    • 234.jpg
  • Content
    • images
      • 234.jpg

以下代碼啟用靜態文件、默認文件和及 MyStaticFiles 的目錄瀏覽:

public void Configure(IApplicationBuilder app)
{
//靜態文件 app.UseStaticFiles(); app.UseFileServer(new FileServerOptions { FileProvider = new PhysicalFileProvider( Path.Combine(Directory.GetCurrentDirectory(), "Content")), RequestPath = "/MyStaticFiles",
//啟用目錄 EnableDirectoryBrowsing = true }); }

EnableDirectoryBrowsing 屬性值為 true 時必須註冊服務 AddDirectoryBrowser

public void ConfigureServices(IServiceCollection services)
{
    services.AddDirectoryBrowser();
}

 

通過URL:https://localhost:5001/MyStaticFiles/訪問時,由於目錄下不存在默認文件,所以會打開文件目錄。

 

 

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※別再煩惱如何寫文案,掌握八大原則!

※產品缺大量曝光嗎?你需要的是一流包裝設計!

能防颱、調節水患 和古墳並立的日本太陽能發電廠

文:宋瑞文(加州能源特約撰述)

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

綠色運輸衝一波 城市的規劃與挑戰

文:詹詒絜(台達電子文教基金會高級專員)

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

聯合國專家:防疫措施恐釀全球缺糧

摘錄自2020年03月26日自由時報報導

武漢肺炎讓全球各地都有民眾因恐慌而瘋狂囤積生活用品、糧食,聯合國糧農組織(FAO)首席經濟學家托雷羅(Maximo Torero)警告,各國實施的防疫措施,恐怕會導致全球糧食短缺。

綜合外電報導,各國為確保物資充足,紛紛祭出提高關稅、限制出口、禁止人口移動等措施。托雷羅表示,從2007年的糧食危機就有觀察到,貿易壁壘會造成價格波動,進而使狀況惡化。雖然目前全球的糧食狀況看似很好,但幾週內糧食問題就會逐漸浮現,並隨著蔬果進入收成季節,於兩個月內惡化。

限制人口流動雖然能有效防止疫情傳播,但邁入收成季的蔬果園也將難以招募到熟練的臨時工,許多作物可能來不及在腐壞前收成。托雷羅也建議消費者,可以透過避免恐慌搶購、囤貨、浪費物資,緩解防疫措施導致的糧食問題。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

報告指亞馬遜雨林去年火災次數飆升三成

摘錄自2020年1月9日星島日報報導

巴西國家太空研究院(INPE)周三發表一份報告顯示,2019年全年在南美洲亞馬遜雨林內發生的火災,比對上一年大幅上升30%。

根據 INPE 提供的數據,在2019年,在亞馬遜地區偵測到的火災多達8萬9178宗,比2018年的6萬8345宗大幅增加。不過,這個數字仍然低於10萬9630宗的歷史性平均紀錄。

亞馬遜森林去年發生的特大山火,引起國際社會廣泛關注。巴西總統博爾索納羅的政策和立場受到各方抨擊,指他上台後只顧經濟利益,把環保及全球氣候暖化的問題置之不理。巴西在2019年斬伐林木及開墾土地的數字,創下10年來新高。如何保護亞馬遜森林成為一個緊急議題。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化

英國新創開發藻類塗層 打造會行光合作用的衣服

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

※教你寫出一流的銷售文案?

流產、死胎層出不窮 南蘇丹隱匿石油業環境報告 犧牲者至今未受保障

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

Quartz.Net系列(七):Trigger之SimpleScheduleBuilder詳解

所有方法圖

 

 SimpleScheduleBuilder方法

RepeatForever:指定觸發器將無限期重複。

WithRepeatCount:指定重複次數

var trigger = TriggerBuilder.Create().WithSimpleSchedule(s=>s.WithIntervalInSeconds(1).RepeatForever()).Build();

 

            var trigger = TriggerBuilder.Create().WithSimpleSchedule(s=>s.WithIntervalInSeconds(1)
                                                                         .WithRepeatCount(10)).Build();

 

注:底層實現是repeatCount+1,也就是總共執行repeatCount+1次

        /// <summary>
        /// Specify a the number of time the trigger will repeat - total number of
        /// firings will be this number + 1.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="repeatCount">the number of seconds at which the trigger should repeat.</param>
        /// <returns>the updated SimpleScheduleBuilder</returns>
        /// <seealso cref="ISimpleTrigger.RepeatCount" />
        /// <seealso cref="RepeatForever" />
        public SimpleScheduleBuilder WithRepeatCount(int repeatCount)
        {
            this.repeatCount = repeatCount;
            return this;
        }

 

 

WithInterval:以毫秒為單位指定重複間隔,由於是TimeSpan也可以指定時分秒

WithIntervalInHours:以小時為單位指定重複間隔

WithIntervalInMinutes:以分鐘單位指定重複間隔

WithIntervalInSeconds:以秒為單位指定重複間隔

            var trigger = TriggerBuilder.Create().WithSimpleSchedule(s=>s .WithIntervalInSeconds(1)
                                                                          .WithInterval(TimeSpan.FromDays(1))
                                                                          .WithIntervalInMinutes(1)
                                                                          .WithIntervalInHours(1)
                                                                          .WithRepeatCount(5))
                                                 .Build();

注:底層都是通過WithInterval實現的

        /// <summary>
        /// Specify a repeat interval in milliseconds.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="timeSpan">the time span at which the trigger should repeat.</param>
        /// <returns>the updated SimpleScheduleBuilder</returns>
        /// <seealso cref="ISimpleTrigger.RepeatInterval" />
        /// <seealso cref="WithRepeatCount(int)" />
        public SimpleScheduleBuilder WithInterval(TimeSpan timeSpan)
        {
            interval = timeSpan;
            return this;
        }

        /// <summary>
        /// Specify a repeat interval in seconds.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <param name="seconds">the time span at which the trigger should repeat.</param>
        /// <returns>the updated SimpleScheduleBuilder</returns>
        /// <seealso cref="ISimpleTrigger.RepeatInterval" />
        /// <seealso cref="WithRepeatCount(int)" />
        public SimpleScheduleBuilder WithIntervalInSeconds(int seconds)
        {
            return WithInterval(TimeSpan.FromSeconds(seconds));
        }

靜態方法:

RepeatMinutelyForever

RepeatMinutelyForTotalCount

RepeatSecondlyForever

RepeatSecondlyForTotalCount

RepeatHourlyForever

RepeatHourlyForTotalCount

var trigger = TriggerBuilder.Create().WithSchedule(SimpleScheduleBuilder.RepeatSecondlyForTotalCount(2)).Build();

 

 /// <summary>
        /// Create a SimpleScheduleBuilder set to repeat forever with a 1 minute interval.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <returns>the new SimpleScheduleBuilder</returns>
        public static SimpleScheduleBuilder RepeatMinutelyForever()
        {
            SimpleScheduleBuilder sb = Create()
                .WithInterval(TimeSpan.FromMinutes(1))
                .RepeatForever();

            return sb;
        }

        /// <summary>
        /// Create a SimpleScheduleBuilder set to repeat forever with an interval
        /// of the given number of minutes.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <returns>the new SimpleScheduleBuilder</returns>
        public static SimpleScheduleBuilder RepeatMinutelyForever(int minutes)
        {
            SimpleScheduleBuilder sb = Create()
                .WithInterval(TimeSpan.FromMinutes(minutes))
                .RepeatForever();

            return sb;
        }

        /// <summary>
        /// Create a SimpleScheduleBuilder set to repeat forever with a 1 second interval.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <returns>the new SimpleScheduleBuilder</returns>
        public static SimpleScheduleBuilder RepeatSecondlyForever()
        {
            SimpleScheduleBuilder sb = Create()
                .WithInterval(TimeSpan.FromSeconds(1))
                .RepeatForever();

            return sb;
        }

        /// <summary>
        /// Create a SimpleScheduleBuilder set to repeat forever with an interval
        /// of the given number of seconds.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <returns>the new SimpleScheduleBuilder</returns>
        public static SimpleScheduleBuilder RepeatSecondlyForever(int seconds)
        {
            SimpleScheduleBuilder sb = Create()
                .WithInterval(TimeSpan.FromSeconds(seconds))
                .RepeatForever();

            return sb;
        }

        /// <summary>
        /// Create a SimpleScheduleBuilder set to repeat forever with a 1 hour interval.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <returns>the new SimpleScheduleBuilder</returns>
        public static SimpleScheduleBuilder RepeatHourlyForever()
        {
            SimpleScheduleBuilder sb = Create()
                .WithInterval(TimeSpan.FromHours(1))
                .RepeatForever();

            return sb;
        }

        /// <summary>
        /// Create a SimpleScheduleBuilder set to repeat forever with an interval
        /// of the given number of hours.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <returns>the new SimpleScheduleBuilder</returns>
        public static SimpleScheduleBuilder RepeatHourlyForever(int hours)
        {
            SimpleScheduleBuilder sb = Create()
                .WithInterval(TimeSpan.FromHours(hours))
                .RepeatForever();

            return sb;
        }

        /// <summary>
        /// Create a SimpleScheduleBuilder set to repeat the given number
        /// of times - 1  with a 1 minute interval.
        /// </summary>
        /// <remarks>
        /// <para>Note: Total count = 1 (at start time) + repeat count</para>
        /// </remarks>
        /// <returns>the new SimpleScheduleBuilder</returns>
        public static SimpleScheduleBuilder RepeatMinutelyForTotalCount(int count)
        {
            if (count < 1)
            {
                throw new ArgumentException("Total count of firings must be at least one! Given count: " + count);
            }

            SimpleScheduleBuilder sb = Create()
                .WithInterval(TimeSpan.FromMinutes(1))
                .WithRepeatCount(count - 1);

            return sb;
        }

        /// <summary>
        /// Create a SimpleScheduleBuilder set to repeat the given number
        /// of times - 1  with an interval of the given number of minutes.
        /// </summary>
        /// <remarks>
        /// <para>Note: Total count = 1 (at start time) + repeat count</para>
        /// </remarks>
        /// <returns>the new SimpleScheduleBuilder</returns>
        public static SimpleScheduleBuilder RepeatMinutelyForTotalCount(int count, int minutes)
        {
            if (count < 1)
            {
                throw new ArgumentException("Total count of firings must be at least one! Given count: " + count);
            }

            SimpleScheduleBuilder sb = Create()
                .WithInterval(TimeSpan.FromMinutes(minutes))
                .WithRepeatCount(count - 1);

            return sb;
        }

        /// <summary>
        /// Create a SimpleScheduleBuilder set to repeat the given number
        /// of times - 1  with a 1 second interval.
        /// </summary>
        /// <remarks>
        /// <para>Note: Total count = 1 (at start time) + repeat count</para>
        /// </remarks>
        /// <returns>the new SimpleScheduleBuilder</returns>
        public static SimpleScheduleBuilder RepeatSecondlyForTotalCount(int count)
        {
            if (count < 1)
            {
                throw new ArgumentException("Total count of firings must be at least one! Given count: " + count);
            }

            SimpleScheduleBuilder sb = Create()
                .WithInterval(TimeSpan.FromSeconds(1))
                .WithRepeatCount(count - 1);

            return sb;
        }

        /// <summary>
        /// Create a SimpleScheduleBuilder set to repeat the given number
        /// of times - 1  with an interval of the given number of seconds.
        /// </summary>
        /// <remarks>
        /// <para>Note: Total count = 1 (at start time) + repeat count</para>
        /// </remarks>
        /// <returns>the new SimpleScheduleBuilder</returns>
        public static SimpleScheduleBuilder RepeatSecondlyForTotalCount(int count, int seconds)
        {
            if (count < 1)
            {
                throw new ArgumentException("Total count of firings must be at least one! Given count: " + count);
            }

            SimpleScheduleBuilder sb = Create()
                .WithInterval(TimeSpan.FromSeconds(seconds))
                .WithRepeatCount(count - 1);

            return sb;
        }

        /// <summary>
        /// Create a SimpleScheduleBuilder set to repeat the given number
        /// of times - 1  with a 1 hour interval.
        /// </summary>
        /// <remarks>
        /// <para>Note: Total count = 1 (at start time) + repeat count</para>
        /// </remarks>
        /// <returns>the new SimpleScheduleBuilder</returns>
        public static SimpleScheduleBuilder RepeatHourlyForTotalCount(int count)
        {
            if (count < 1)
            {
                throw new ArgumentException("Total count of firings must be at least one! Given count: " + count);
            }

            SimpleScheduleBuilder sb = Create()
                .WithInterval(TimeSpan.FromHours(1))
                .WithRepeatCount(count - 1);

            return sb;
        }

        /// <summary>
        /// Create a SimpleScheduleBuilder set to repeat the given number
        /// of times - 1  with an interval of the given number of hours.
        /// </summary>
        /// <remarks>
        /// <para>Note: Total count = 1 (at start time) + repeat count</para>
        /// </remarks>
        /// <returns>the new SimpleScheduleBuilder</returns>
        public static SimpleScheduleBuilder RepeatHourlyForTotalCount(int count, int hours)
        {
            if (count < 1)
            {
                throw new ArgumentException("Total count of firings must be at least one! Given count: " + count);
            }

            SimpleScheduleBuilder sb = Create()
                .WithInterval(TimeSpan.FromHours(hours))
                .WithRepeatCount(count - 1);

            return sb;
        }

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

Day8-微信小程序實戰-交友小程序-首頁用戶列表渲染及多賬號調試及其點贊功能的實現

在這之前已經把編輯個人的所有信息的功能已經完成了

之後先對首頁的列表搞動態的,之前都是寫死的靜態

1、之前都是把好友寫死的,現在就在js裏面定義一個數組,用循環來動態的綁定

在onReady中定義,取真實的數據給定義的列表數組list  

通過調用  db.collection(‘users’).get()  這裏沒有加其他的限制,得到的就是所有的數據了,拿到全部的數據之後就會觸發then方法了

用then返回的res中有一個data的列表集合,有一個注意的點就是,這樣子讀取是吧數據庫中的數據的全部字段,但是我們需要用的只是

用戶的頭像和點贊數、用戶昵稱,其他的數據其實是不需要的

可以加一個field方法,可以要求返回的字段是哪些的

 

可以看到是只有一個用戶,我們為了模擬的話,就可以多賬號進行調試,

 

 1、創立多賬號

    ①首先這個多賬號的一定要是測試號,所以先進入微信的管理後台 https://mp.weixin.qq.com/

    ②進入 【成員管理】添加項目成員

    ③回到微信開發者工具中-》工具-》多賬號調試-》可以通過添加虛擬測試號來進行測試的,不用真實的微信號都可以

 

之後就是對點贊的功能進行設計了(就可以在index.wxml中給點贊的小心上加一個點擊事件即可了

(小細節在小程序中規定,在客戶端中讀取用戶列表的時候,一般不會把整個數據庫的用戶都讀取出來的,是有一個限制的

一般都是把前二十條數據給讀取出來的,如果數據一多的話,一般都是進行分頁處理了–一般都是用數據庫中的collection.skip和collection.limit,這兩個東西一起配合的話就可以做下拉加載的功能了)

由於這個點贊是要對找到用戶的id地址的,所以在wxml中給點贊這個圖標加上一個id自定義屬性的掛載

 

data-id="{{ item._id}}"

這個東西的用處就是,在點擊這個心心的時候就可以拿到這個自定義的屬性id了  

通過把handleLinks(ev)函數中把ev打印出來發現,這個自定義屬性id 的位置在

 ev.target.dataset.id

console.log就是用來測試的,如果沒效果的話,一般都是直接在點擊事件後面通過promise 的then把res打印出來看看情況是怎麼樣的

***有時候這些點擊事件無法觸發的話,就可以在檢查一下樣式,可能這個區域在前端显示是在這裏,但是實際上是在其他的地方,

 

 

 也就是布局引起的問題了

 

 

 

 可以看到這裏就是碰到的是點贊的這個圖標,但是這個樣式是在左上角進行了渲染的

這個時候為了演示把,就把自定義屬性,和點擊事件放在點贊圖標還有點贊數包含的這個text裏面了

<text bindtap="handleLinks" data-id="{{ item._id}}" >
          <!-- 點贊圖標 -->
              <text class="iconfont icondianzan"
              ></text>
          <!-- 點贊數 -->
              <text>{{ item.links }}</text>
          </text>

改完之後,再點擊心心或者是數量,就可以正常的進行點贊了

  但是發現只有給自己點贊的時候才可以改變點贊的數量,而改其他人點贊的時候就改不了

比如:

 

 

 這就是一個權限的問題了也就是只能改自己的數據(點贊數)改不了別人的數據l

 

 

因為在小程序端中,由於用戶可以直接對數據庫進行操作,所以會有一定的風險,所以就通過這個訪問權限來進行了限制

那?

怎麼修改別人的數據呢?—這個操作就要在服務端來進行操作了!  也就是在雲函數中去完成一個雲函數的操作了

 

下面就是講解 如何在 服務端來對数字字段來進行更改!

 

二、點贊功能實現與update雲函數

 由於要在服務端來做的話,就可以把這一塊的部分代碼刪掉了

  handleLinks(ev){
    let id = ev.target.dataset.id;
    db.collection('users').doc(id).update({
      data : {
        links : 5
      }
    }).then((res)=>{
      console.log(res)
    }); 
  }

需要新創一個雲函數(新建一個node.js雲函數

 

這些默認的結構都是可以刪掉的了

 

 之後就是參考 微信開放文檔 雲開發-》SDK文檔->數據庫-》collection->update-》示例代碼demo

其中:這個就是指定了數據庫的環境

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})

然後就是在服務端拿到數據庫db

const db = cloud.database()

然後可以在示例代碼中看到async這個異步的操作

直接複製 try catch

try {
    return await db.collection('todos').where({
      done: false
    })
    .update({
      data: {
        progress: _.inc(10)
      },
    })
  } catch(e) {
    console.error(e)
  }

return就是返回一個異步的數據,而catch就是返回錯誤信息

主要修改的就是 db.collecion()中要反問那個數據庫表單,這裏不能寫死為users,因為可能其他的地方也是要用到更新的這個功能的

所以最好就是把update這個雲函數寫成一個通用的方式

其中雲函數入口函數 

exports.main = async (event, context) => {  這個裡面的event就是前端傳參過來的對象了 就訪問 event.colletion,然後不用where而是用doc 再把event的doc也傳進來,這 ***小知識點:ES6的擴展運算符 。。。 (三個點)

更新成功了之後,就可以返回結果到前台了

這個就是update雲函數中js文件的代碼(傳進去的doc實際上是用戶的_id

 // 雲函數入口文件
const cloud = require('wx-server-sdk')

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})
const db = cloud.database()
// 雲函數入口函數
exports.main = async (event, context) => {
  try {
    return await db.collection(event.collection).doc(event.doc)
      .update({
        data: {
         ...event.data 
        },
      })
  } catch (e) {
    console.error(e)
  }
}

View Code

把雲函數寫好之後,這個時候雲函數還是在本地,要把這個雲函數傳到雲開發平台上

 

上傳了之後一定要去雲平台-》雲函數中去檢查一下

 

之後就可以調用這個雲函數了

再回到index.js 點贊的方法 handleLinkes方法中進行設置即可;

 

 如果雲函數沒問題,可能是雲函數裏面定義的env出了問題,就可以寫死了,傳入自己的那個環境,就不用默認的那個環境了

【注意】修改了雲函數記得要重新上傳到雲平台才行

 

 

 

 (因為在服務端是不會受到數據庫權限的限制的)

後面要優化的就是(上面的點贊是寫死給多少links的,並且不能點完之後立馬更新

可以把數據庫的links讀出來,+1之後再寫入,但是這樣的話就多了一個數據庫的操縱了  ,但是數據庫本身就提供了累加或者累減等運算的操作的

(這樣的話就只需要一次的數據庫讀取即可了)

在開放文檔 db.command裏面就有很多的方法

https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-sdk-api/database/command/Command.inc.html

示例代碼
將一個 todo 的進度自增 10:

const _ = db.command
db.collection('todos').doc('todo-id').update({
  data: {
    progress: _.inc(10)
  }
})

為了在服務端不把運算給寫死了,一般都是把運算直接通過前端來傳入的

由於前端不認識下劃線這種操作,因為前端要先解析,之後再把東西傳到服務端的,所以就可以在前端給服務端傳一個字符串的話

然後再在服務端解析即可

 data : "{links : _.inc(1)}"

在前端把這個字符串傳入到服務端中,之後就可以在服務端那邊對這個字符串進行解析了

所以在update雲函數中 就要對event.data這個傳過來的數據進行判斷,判斷它的類型,是普通的還是字符串類型的,如果是字符串類型的話就要進行解析

用js裏面的eval方法,它是把字符串轉成 js 語句的

 if(typeof event.data == 'string'){
      event.data =  eval('(' + event.data + ')')
    }

即可了(點一下心心就可以讓點贊數+1)

後面有空的話,可以繼續進行優化,也就是對一次的點贊數進行限制,或者是點一下加+1,再點一下就是取消了就-1了

後面就是要把點贊了之後,實時的把點贊數進行更新

 

可以看到給服務端那邊上傳之後,對數據庫進行了更新之後,then返回的結果res,中有一個是updated==1,就可以進行if判斷了

再用for循環對列表中的每一個元素判斷,是不是現在被點擊點贊的這個id

let updated = res.result.stats.updated;
    if(updated){
      // 先用擴展運算符 克隆一份數組
      let cloneListData = [...this.data.listData];
      for(let i = 0;i < cloneListData.length ; i++){
        if( cloneListData[i]._id == id){ 
          cloneListData[i].links++;
        }
      }
      this.setData({
        listData : cloneListData
      });
    }

點贊數增加 就是通過_inc 但是在服務端中的update函數中是用全局的,不能寫死,所以運算的規則就通過前端傳過去

為了以後其他的頁面也有更新功能的話做準備了

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

一起玩轉微服務(7)——單一職責

 

單一職責

單一職責原則(Single Responsibility Principle, SRP):一個類只負責一個功能領域中的相應職責,或者可以定義為:就一個類而言,應該只有一個引起它變化的原因。

單一職責原則是實現高內聚、低耦合的指導方針,它是最簡單但又最難運用的原則

單一職責原則是最簡單的面向對象設計原則,它用於控制類的粒度大小

設計原則很重要的一點就是簡單,單一職責,也就是我們經常所說的專人干專事。

一個單元(一個類、函數或者微服務)應該有且只有一個職責。無論如何,一個微服務不應該包含多於一個的職責。職責單一的後果之一就是職責單位(微服務,類,接口,函數)的數量劇增。據說Amazon,Netflix這些採用微服務架構的網站一個小功能就會調用幾十上百個微服務。但是相較於每個函數都是多個業務邏輯或職責功能的混合體的情況,維護成本還是低很多的。 SRP中的“單一職責”是個比較模糊的概念。對於函數,它可能指單一的功能,不涉及複雜邏輯;但對於類或者接口,它可能是指對單一對象的操作,也可能是指對該對象單一屬性的操作。總而言之,單一職責原則就是為了讓代碼邏輯更加清晰,可維護性更好,定位問題更快的一種設計原則。

什麼是高內聚低耦合?

這犀利的措辭一看就是來自開發界的術語。高內聚是說一個功能模塊最好僅完成一個獨立的子功能並且完成的很好。低耦合是指模塊與模塊之間盡量獨立/聯繫少/接口簡單。

這個原則出現的背景是為了讓程序“可復用/可擴展/夠靈活/可維護”。干過一陣子產品的人對這幾個詞應該都不陌生。對於程序設計者來說,這幾個詞是十分重要的,不亞於產品經理口中的“用戶體驗”(原則or擋箭牌)。

優點

單一職責的優點如下:

•類的複雜性降低,實現什麼職責都有清晰明確的定義。•可讀性提高,複雜性降低。•可維護性提高,可讀性提高。•變更引起的風險降低,變更是必不可少的,如果接口的單一職責做得好,一個接口修改只對相應的實現類有影響,對其他的接口無影響,這對系統的擴展性、維護性都有非常大的幫助。

記得在三字經裡邊有這樣一段 教之道,貴以專(出自三字經) 說的就是無論學習還是構建團隊,最重要的是專才,而不是全才。就好比一個足球隊,如果都是前鋒或者都是後衛,那麼這樣的球隊一定不能出成績,反而是將各個位置上的人進行統一協調,根據分工不同,共同協作,形成1+1>2的效果,那麼這樣的團隊就非常容易出成績。

有很多公司為了趕進度,經常會招聘一些所謂的全能型人才,但是這種人往往專業的程度不夠,當遇到某些棘手的問題的時候,往往不能夠非常快速的解決問題。從而導致最終交付的質量較差。

單一職責的目的

實施單一職責的目的如下:

•以類來隔離需求功能點,這樣當一個點的需求發生變化的時候,不會影響別的類的邏輯,這個和設計模式中的開閉原則類似,對於擴展持開放態度,對於修改持關閉態度。•是一個原子模塊級的粒度,至於原子的粒度到底是什麼樣的,應該因業務而異,設計的過程中同時考慮業務的擴展,所以這就要求在設計的過程中,必須有業務專家共同參与,共同規避風險。•粒度小,靈活,復用性強,方便更高一級別的抽象。

每個微服務單獨運行在獨立的進程中,能夠實現松耦合,並且獨立部署。

如何做

分3步:

1.把一個具體的問題抽象成一類問題;

2.根據用戶體驗流程劃分功能模塊;

3.針對每個功能設計封閉的解決方案。

最佳實踐

在實際工作中,有一個經常會用到的設計模式,DAO模式,又叫數據訪問對象,裏面定義了數據庫中表的增、刪、改、查操作,按照單一職責原則,為什麼不把增、刪、改、查分別定義成四種接口?這是因為數據庫的表操作,基本上就是這四種類型,不可能變化,所以沒有必要分開定義,反而經常變化的是數據庫的表結構,表結構一變,這四種操作都要跟着變。所以通常我們會針對一張表實現一個DAO,一張表就代表一種類型的職責。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化