在前一篇部落格《C#開發BIMFACE系列50 Web網頁中使用jQuery載入模型與圖紙》中詳細介紹了在網頁中使用jQuery載入模型與圖紙
本篇部落格主要介紹Web網頁中使用Vue.js載入模型與圖紙以及其他的應用開發。開發步驟與使用jQuery基本相同,更確切地將就是將jQuery語法翻譯成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
下載後直接在網頁中引用
下載地址:https://bimface.com/developer-guide/984
下載的檔案是一個壓縮包,解壓後目錄結構如下:
另外2個目錄是用於離線資料包功能,這裡只需要把BimfaceSDKLoader@latest-release.js檔案拷貝到專案中即可,建議增加檔案版本號,修改為BimfaceSDKLoader@latest-release-3.6.159.js。有如下兩種引用方式,選擇任一種都可以。
方式1:引用本地檔案
方式2:引用BIMFACE官方線上檔案。優點:一直保持最新版本。
檢視BIMFACE需要使用ViewToken,ViewToken 代表對單個模型/整合模型/模型對比的訪問許可權。首先根據 FileId 呼叫介面獲取AccessToken,通過AccessToken呼叫介面獲取ViewToken。
Web.aspx、Web.html、Web.cshtml 中使用Ajax呼叫一般處理程式或者MVC控制器是最常用的方法。jQuery中針對Ajax封裝了幾個常用的方法,簡單、實用、易用,示例如下:
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 }
但是Vue.js中並沒有直接提供Ajax的相關方法。在Vue.js 1.x 版本中使用到 vue-resource 庫,在2.x版本推薦使用 Axios 來完成 Ajax 請求。Axios 是一個基於 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。GitHub下載地址:https://github.com/axios/axios
下載完成後在專案中引用
使用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
一般處理程式
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 }
主要使用了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。歡迎大家下載使用。