C#開發BIMFACE系列51 Web網頁中使用Vue.js載入模型與圖紙

張傳寧發表於2021-10-19
BIMFACE二次開發系列目錄     【已更新最新開發文章,點選檢視詳細】
C#開發BIMFACE系列51 Web網頁中使用Vue.js載入模型與圖紙

在前一篇部落格《C#開發BIMFACE系列50 Web網頁中使用jQuery載入模型與圖紙》中詳細介紹了在網頁中使用jQuery載入模型與圖紙

本篇部落格主要介紹Web網頁中使用Vue.js載入模型與圖紙以及其他的應用開發。開發步驟與使用jQuery基本相同,更確切地將就是將jQuery語法翻譯成Vue.js來表達。

步驟1:下載並引用 Vue.js

Vue.js 官方目前釋出的版本已經到3.X。之前廣泛使用的是2.X,兩個版本功能相差很大。本文以2.x版本為例進行講解演示。

Vue.js 是我們中國人創造發明的,作者叫尤雨溪。

尤雨溪在谷歌工作,工作過程中受到Angular的啟發,從中提取自己所喜歡的部分,開發出了一款輕量框架。
2014年1月,正式對外發布了Vue.Js第一個版本。具有以下特點:

  • 它是一套構建使用者介面的漸進式框架。
  • 只關注檢視層,採用自底向上增量開發的設計。
  • 它的目標是通過儘可能簡單的 API 實現響應的資料繫結和組合的檢視元件。 

Vue.js  入門學習非常簡單,目前國內很多大廠都在使用它。

GitHub下載地址: https://github.com/vuejs/vue

C#開發BIMFACE系列51 Web網頁中使用Vue.js載入模型與圖紙

C#開發BIMFACE系列51 Web網頁中使用Vue.js載入模型與圖紙

下載後直接在網頁中引用

步驟2:下載並引用 BIMFace JSSDK

下載地址:https://bimface.com/developer-guide/984

C#開發BIMFACE系列51 Web網頁中使用Vue.js載入模型與圖紙

下載的檔案是一個壓縮包,解壓後目錄結構如下:

C#開發BIMFACE系列51 Web網頁中使用Vue.js載入模型與圖紙

另外2個目錄是用於離線資料包功能,這裡只需要把BimfaceSDKLoader@latest-release.js檔案拷貝到專案中即可,建議增加檔案版本號,修改為BimfaceSDKLoader@latest-release-3.6.159.js。有如下兩種引用方式,選擇任一種都可以。

方式1:引用本地檔案

方式2:引用BIMFACE官方線上檔案。優點:一直保持最新版本。

步驟3:根據 FileId 獲取 ViewToken

檢視BIMFACE需要使用ViewToken,ViewToken 代表對單個模型/整合模型/模型對比的訪問許可權。首先根據 FileId 呼叫介面獲取AccessToken,通過AccessToken呼叫介面獲取ViewToken。

Web.aspx、Web.html、Web.cshtml 中使用Ajax呼叫一般處理程式或者MVC控制器是最常用的方法。jQuery中針對Ajax封裝了幾個常用的方法,簡單、實用、易用,示例如下:

C#開發BIMFACE系列51 Web網頁中使用Vue.js載入模型與圖紙
 1 // 載入模型或圖紙
 2 function loadBIMFile(bimFaceFileId) {
 3     $("#bimContainer").empty();//清空容器內容。解決切換不同圖紙時會保留上一次圖紙內容的問題。
 4 
 5     $.ajax({
 6         url: "../Handlers/GetViewTokenHandler.ashx",
 7         data: { fileId: bimFaceFileId },
 8         dataType: "json",
 9         type: "GET",
10         async: false, //同步(此處設定為同步或者非同步都可以)
11         success: function (data) {
12             if (data.code == true) {
13                 showBIMModel(data.viewToken);// 載入BIMFACE模型
14             } else {
15                 alert("【警告】\r\n" + data.message);
16             }
17         },
18         error: function (e) {
19             console.log('GetViewTokenHandler.ashx請求發生異常:' + e);
20             alert("【異常】\r\n" + '獲取ViewToken發生異常');
21         },
22         complete: function (XMLHttpRequest, status) {
23 
24         }
25     });
26 }
View Code

但是Vue.js中並沒有直接提供Ajax的相關方法。在Vue.js 1.x 版本中使用到 vue-resource 庫,在2.x版本推薦使用 Axios 來完成 Ajax 請求。Axios 是一個基於 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。GitHub下載地址:https://github.com/axios/axios

C#開發BIMFACE系列51 Web網頁中使用Vue.js載入模型與圖紙

 C#開發BIMFACE系列51 Web網頁中使用Vue.js載入模型與圖紙

 下載完成後在專案中引用

使用axiox請求一般處理程式的程式碼如下:

 1 loadBIMFile(bimFaceFileId) { // 載入模型或圖紙
 2     document.getElementById("bimContainer").innerHTML = "";//清空容器內容。解決切換不同圖紙時會保留上一次圖紙內容的問題。
 3 
 4     // 根據FileId,查詢ViewToken
 5     axios.get('../Handlers/GetViewTokenHandler.ashx', {
 6         params: {
 7             fileId: bimFaceFileId
 8         }
 9     })
10         // .then(function (response) {  /* 匿名函式的指標,指向函式操作的本身。所以then 函式中無法呼叫 Vue 物件中定義的函式 */
11         //    if (response.data.code == true) {
12         //        alert('response.data.viewToken:' + response.data.viewToken);
13         //        this.showBIMModel(response.data.viewToken);// 載入BIMFACE模型
14         //    } else {
15         //        alert("【警告】\r\n" + data.message);
16         //    }
17         //})
18         .then((response) => {  /* 箭頭函式的指標,指向 Vue 元件的本身 */
19             if (response.data.code == true) {
20                 this.showBIMModel(response.data.viewToken);// 載入BIMFACE模型
21             } else {
22                 alert("【警告】\r\n" + data.message);
23             }
24         }).catch((error) => {
25             console.log('GetViewTokenHandler.ashx請求發生異常:' + error);
26             alert("【異常】\r\n" + '獲取ViewToken發生異常 ' + error);
27         });
28 },

特別說明

Vue.js 使用 axios 的回撥函式中 this 指向問題。then() 回撥函式

  • 回撥函式寫成箭頭函式(上述程式碼第18行),則回撥函式的指標指向 Vue 元件本身,可以通過 this 關鍵字呼叫 Vue 元件其內部定義的屬性、方法等。
  • 回撥函式寫成匿名函式(上述程式碼第10行),則回撥函式的指標指向函式操作的本身,此時如果用this去呼叫Vue元件中定義的屬性、方法會報錯。

所以此處寫成箭頭函式形式,然後呼叫其他方法。

Axios 是一個基於 Promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。

本質上也是對原生XHR的封裝,只不過它是 Promise 的實現版本,符合最新的ES規範,有以下特點:

  • 從瀏覽器中建立 XMLHttpRequests
  • 從 node.js 建立 http 請求
  • 支援 Promise API
  • 攔截請求和響應
  • 轉換請求資料和響應資料
  • 取消請求
  • 自動轉換 JSON 資料
  • 客戶端支援防禦 XSRF

具體請參考Axios中文文件 http://www.axios-js.com/zh-cn

C#開發BIMFACE系列51 Web網頁中使用Vue.js載入模型與圖紙

一般處理程式

 1 using System;
 2 using System.Configuration;
 3 using System.Text;
 4 using System.Web;
 5 
 6 using BIMFace.SDK.CSharp.API;
 7 using BIMFace.SDK.CSharp.Common.Extensions;
 8 using BIMFace.SDK.CSharp.Common.Log;
 9 
10 namespace BIMFace.SDK.CSharp.Sample.Handlers
11 {
12     /// <summary>
13     /// GetViewTokenHandler 的摘要說明
14     /// </summary>
15     public class GetViewTokenHandler : IHttpHandler
16     {
17 
18         public void ProcessRequest(HttpContext context)
19         {
20             context.Response.ContentEncoding = Encoding.UTF8;
21 
22             string bimfaceAppKey = ConfigurationManager.AppSettings["BIMFACE_AppKey"];
23             string bimfaceAppSecret = ConfigurationManager.AppSettings["BIMFACE_AppSecret"];
24             if (bimfaceAppKey.IsNullOrWhiteSpace())
25             {
26                 LogUtility.Error("web.config 中未配置 BIMFACE_AppKey。");
27             }
28             if (bimfaceAppSecret.IsNullOrWhiteSpace())
29             {
30                 LogUtility.Error("web.config 中未配置 BIMFACE_AppSecret。");
31             }
32 
33             string fileId = context.Request["fileId"];
34             IBasicApi basicApi = new BasicApi();
35             try
36             {
37                 string accessToken = basicApi.GetAccessToken(bimfaceAppKey, bimfaceAppSecret).Data.Token;
38                 string viewToken = basicApi.GetViewTokenByFileId(accessToken, fileId.ToLong()).Data;
39 
40                 var response = new
41                 {
42                     code = true,
43                     message = "",
44                     viewToken = viewToken
45                 };
46 
47                 context.Response.Write(response.SerializeToJson());
48             }
49             catch (Exception ex)
50             {
51                 var response = new
52                 {
53                     code = false,
54                     message = "獲取模型ViewToken失敗。",
55                     viewToken = ""
56                 };
57 
58                 context.Response.Write(response.SerializeToJson());
59 
60                 LogUtility.Error("GetViewTokenHandler 產生異常:" + ex);
61             }
62 
63             context.Response.End();
64         }
65 
66         public bool IsReusable
67         {
68             get
69             {
70                 return false;
71             }
72         }
73     }
74 }
步驟4:根據ViewToken載入模型或者圖紙

主要使用了JSSDK中的BimfaceSDKLoaderConfig類與BimfaceSDKLoader物件,示例完整的程式碼如下:

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4     <meta charset="utf-8" />
  5     <title>網頁中使用Vue.js載入模型/圖紙</title>
  6     <style>
  7         * {
  8             margin: 0;
  9             padding: 0;
 10         }
 11 
 12         html, body {
 13             height: 100%;
 14             overflow: hidden;
 15         }
 16 
 17         .viewer-wrap {
 18             width: 100%;
 19             height: 100%;
 20             background: rgb(50, 50, 55) none repeat scroll 0% 0%;
 21         }
 22     </style>
 23     <script src="../Content/js/Vue-2.6.14.min.js"></script>
 24     <script src="../Content/js/axios-0.23.0.min.js"></script>
 25     <script src="https://static.bimface.com/api/BimfaceSDKLoader/BimfaceSDKLoader@latest-release.js"></script>
 26 </head>
 27 <body>
 28     <div id="bimContainer" class="viewer-wrap">
 29 
 30     </div>
 31 
 32     <script type="text/javascript">
 33         window.onload = function () {
 34             //var vm =
 35             new Vue({
 36                 el: '#bimContainer',
 37                 data: {
 38                     /* bimFaceFileId 呼叫上傳介面把檔案傳送到BIMFACE伺服器後返回fileID,開發者記錄下來。
 39                      * fileId:10000709359577 模型
 40                      * fileId:10000709090473 圖紙
 41                      * */
 42                     fileId: 10000709359577,
 43                     app: null,
 44                     viewer2D: null,
 45                     viewer3D: null,
 46                     modelViewer: {
 47                         toolbar: undefined,  // 工具條
 48                         annotationmanager: undefined,  // annotation的繪製管理器
 49                         annotationToolbar: undefined,
 50                         annotationControl: undefined   // 重寫annotation的儲存、取消
 51                     }
 52                 },
 53                 beforeCreate: function () {
 54                     /* 在例項初始化之後,資料觀測(data observer) 和 event/watcher 事件配置之前被呼叫 */
 55                     console.log('beforCreate');
 56                 },
 57                 created: function () {
 58                     /* 在例項建立完成後被立即呼叫。
 59                      * 在這一步,例項已完成以下配置:資料觀測(data observer)、屬性和方法的運算、watch/event 事件回撥。
 60                      * 然後,掛在階段還未開始,$el 屬性目前不可見。
 61                      */
 62                     console.log('created');
 63                 },
 64                 beforeMount: function () {
 65                     /* 在掛載開始之前被呼叫:相關的渲染函式首次被呼叫*/
 66                     console.log('beforMount');
 67                 },
 68                 mounted() {
 69                     /* el被新建立的 vm.$el 替換,掛載成功 */
 70                     console.log('mounted');
 71 
 72                     this.loadBIMFile(this.fileId);
 73                 },
 74                 beforeUpdate: function () {
 75                     /* 資料更新時呼叫 */
 76                     console.log('beforeUpdate');
 77                 },
 78                 updated: function () {
 79                     /* 元件 DOM 已經更新,元件更新完畢 */
 80                     console.log('updated');
 81                 },
 82                 methods: {
 83                     loadBIMFile(bimFaceFileId) { // 載入模型或圖紙
 84                         document.getElementById("bimContainer").innerHTML = "";//清空容器內容。解決切換不同圖紙時會保留上一次圖紙內容的問題。
 85 
 86                         // 根據FileId,查詢ViewToken
 87                         axios.get('../Handlers/GetViewTokenHandler.ashx', {
 88                             params: {
 89                                 fileId: bimFaceFileId
 90                             }
 91                         })
 92                             // .then(function (response) {  /* 匿名函式的指標,指向函式操作的本身。所以then 函式中無法呼叫 Vue 物件中定義的函式 */
 93                             //    if (response.data.code == true) {
 94                             //        alert('response.data.viewToken:' + response.data.viewToken);
 95                             //        this.showBIMModel(response.data.viewToken);// 載入BIMFACE模型
 96                             //    } else {
 97                             //        alert("【警告】\r\n" + data.message);
 98                             //    }
 99                             //})
100                             .then((response) => {  /* 箭頭函式的指標,指向 Vue 元件的本身 */
101                                 if (response.data.code == true) {
102                                     this.showBIMModel(response.data.viewToken);// 載入BIMFACE模型
103                                 } else {
104                                     alert("【警告】\r\n" + data.message);
105                                 }
106                             }).catch((error) => {
107                                 console.log('GetViewTokenHandler.ashx請求發生異常:' + error);
108                                 alert("【異常】\r\n" + '獲取ViewToken發生異常 ' + error);
109                             });
110                     },
111 
112                     showBIMModel(viewToken) {// 顯示BIMFACE模型
113                         var loaderConfig = new BimfaceSDKLoaderConfig(); // 設定BIMFACE JSSDK載入器的配置資訊
114                         loaderConfig.viewToken = viewToken;
115                         BimfaceSDKLoader.load(loaderConfig, this.successCallback, this.failureCallback);  // 載入BIMFACE JSSDK載入器
116                     },
117 
118                     successCallback(viewMetaData) { // 載入成功回撥函式
119                         /* modelViewer 是全域性物件,它與具體的圖紙或者模型一一對應。如果切換了圖紙/模型,則需要將其重置,然後在後續操作中再建立。*/
120                         modelViewer = {
121                             toolbar: undefined,  // 工具條
122                             annotationmanager: undefined,  // annotation的繪製管理器
123                             annotationToolbar: undefined,
124                             annotationControl: undefined   // 重寫annotation的儲存、取消
125                         };
126 
127                         var dom4Show = document.getElementById('bimContainer'); // 獲取DOM元素
128 
129                         if (viewMetaData.viewType == "3DView") {
130                             var webAppConfig = new Glodon.Bimface.Application.WebApplication3DConfig();
131                             webAppConfig.domElement = dom4Show;
132 
133                             app = new Glodon.Bimface.Application.WebApplication3D(webAppConfig); // 建立WebApplication
134                             app.addView(viewMetaData.viewToken);//temp_ViewToken   // 新增待顯示的模型
135 
136                             viewer3D = app.getViewer();  // 從WebApplication獲取viewer3D物件
137 
138                             // 監聽新增view完成的事件
139                             viewer3D.addEventListener(Glodon.Bimface.Viewer.Viewer3DEvent.ViewAdded, function () {
140                                 // 呼叫viewer3D物件的Method,可以繼續擴充套件功能
141                                 modelViewer.toolbar = dom4Show.getElementsByClassName("bf-toolbar-bottom");
142 
143                                 //自適應螢幕大小
144                                 window.onresize = function () {
145                                     viewer3D.resize(document.documentElement.clientWidth, document.documentElement.clientHeight - 40);
146                                 }
147                             });
148                         }
149                         else if (viewMetaData.viewType == "drawingView") {
150 
151                             var webAppConfig = new Glodon.Bimface.Application.WebApplicationDrawingConfig();
152                             webAppConfig.domElement = dom4Show;
153                             webAppConfig.viewToken = viewMetaData.viewToken;
154 
155                             app = new Glodon.Bimface.Application.WebApplicationDrawing(webAppConfig); // 建立WebApplication
156                             app.load(viewMetaData.viewToken);//viewToken  // 新增待顯示的模型
157 
158                             viewer2D = app.getViewer();// 從WebApplication獲取viewerDrawing物件
159 
160                             this.drawingViewExtend(viewer2D);    // 監聽新增view完成的事件
161                         }
162                     },
163 
164                     failureCallback(error) {// 載入失敗回撥函式
165                         console.log(error);
166                     },
167 
168                     drawingViewExtend(viewer2D) {// 向量dwg擴充套件功能
169                         var viewerEvents = Glodon.Bimface.Viewer.ViewerDrawingEvent;
170 
171                         // 註冊 ComponentsSelectionChanged ViewerDrawing圖元點選選中事件
172                         viewer2D.addEventListener(viewerEvents.ComponentsSelectionChanged, function () {
173                             //ToTo 通過圖元ID找到圖框ID
174                         });
175 
176                         // 註冊 Loaded ViewerDrawing載入完畢事件
177                         viewer2D.addEventListener(viewerEvents.Loaded, function () {
178                             var dom4Show = document.getElementById('bimContainer'); // 獲取DOM元素
179                             modelViewer.toolbar = dom4Show.getElementsByClassName('.bf-toolbar-bottom');
180 
181                             //自適應螢幕大小
182                             window.onresize = function () {
183                                 viewer2D.resize(document.documentElement.clientWidth, document.documentElement.clientHeight - 40);
184                             }
185                         });
186                     }
187                 }
188             });
189         }
190     </script>
191 
192 </body>
193 </html>

 

 《BIMFace.SDK.CSharp》開源SDK。歡迎大家下載使用。

C#開發BIMFACE系列51 Web網頁中使用Vue.js載入模型與圖紙
BIMFACE二次開發系列目錄     【已更新最新開發文章,點選檢視詳細】

相關文章