友好开放空间是一个非常年轻的框架,但是已经知道如何运行:-)
在有关“友好的开放空间”开发的本文中,我们将掌握浏览器中模板的呈现方式,并在本地文件数据库上启动应用程序。
框架的核心在客户端上支持两种类型的模板组装:
- 完整的客户端渲染
- 请求将模板呈现给服务器,然后在浏览器窗口中输出模板。
第一种模式具有一个特征,向服务器请求呈现模板所需的数据,即 客户端执行FSQL查询。 如果使用访问限制和fosAccess模块,则没有特别的危险,但是有可能通过copy pasteur卸载原始数据。 但是,这种方法大大减少了服务器上的负载。
第二种渲染类型已经没有此功能。 客户端发送模板参数,并且已经从HTML服务器接收。 是的,服务器上的负载肯定会增加,但是这种方法更适合开放式Internet解决方案。
准备应用程序并进行设置
因此,我们面临着创建一页应用程序的任务,该应用程序将在客户端呈现2个模板(窗口)。 鉴于一项相当简单的任务,我们将没有MySQL数据库和投影,因此我们会将所有FSQL工作定向到一个文件,即 我们将使用文件上的数据库来使用框架的内部机制。 好吧,让我们开始吧。
创建目录:
模板-模板目录
css-css文件目录
fos-下载最新的beta beta
friendlyopenspace.site/en/download将烦人的favicon.ico放置在应用程序的根目录中:
favicon.ico另外,我们立即将样式文件放置在css目录中:
window.css和
styles.css接下来,创建application.js应用程序文件本身:
var fos = require("./fos/fos"); fos.module({ name: "application.js", dependencies: [ "fos:NServer/Application.js", ], module: function(application) { application.setSettings({ port: 3001, packages: [], dynamicLoading: true, clientRenderingMode: "client", dataClient: { defaultConnection: "default", connections: { default: { type: "file", file: "data.fosdb" } }, }, onInitialize: function(a_event) { if (!a_event.error) { application.run(); } else { console.error(a_event.error); } } }); application.getRouter().add([ { route: "", controller: "fos:NServer/NControllers/Tmpl.js", source: "templates/page.tmpl", }, { route: "/css/*", controller: "fos:NServer/NControllers/File.js", source: "css", }, { route: "/templates/*", controller: "fos:NServer/NControllers/File.js", source: "templates", }, { route: "favicon.ico", controller: "fos:NServer/NControllers/File.js", source: "favicon.ico", }, ]); application.initialize(); } });
现在让我们看一下application.js文件的内容
我们禁用了所有不需要的软件包(setSettings方法的packages参数):
... application.setSettings({ port: 3001, packages: [], dynamicLoading: true, clientRenderingMode: "client", ...
对我们来说新的clientRenderingMode应用程序参数负责客户端上的呈现类型,并具有两个值:
“客户端”-渲染完全由浏览器执行。 客户端独立加载依赖项并执行FSQL查询到服务器,然后客户端自行收集HTML。
“服务器”-客户端向服务器发出渲染模板的请求,并接收准备好的HTML作为响应
... packages: [], dynamicLoading: true, clientRenderingMode: "client", dataClient: { defaultConnection: "default", ...
我们的最后一项创新是将数据库连接到文件上。 如果没有能力处理具有表结构的配置变量,该框架将无法完全正常工作。 因此,我们将使用常规文件来代替MYSQL。
... defaultConnection: "default", connections: { default: { type: "file", file: "data.fosdb" } }, }, ...
从上面的摘录中可以看出,在这种情况下,数据库类型(类型参数)为“文件”,并且唯一的文件连接参数应包含数据文件的路径。 如果文件丢失,则应用程序将自行创建文件。
创建页面模板
现在是时候创建一个应用程序页面模板文件template / page.tmpl,我们已经在根URL路由中注册了它。
//~OPTIONS { args:{ fosInclude: ["css/styles.css"], } } //~BLOCK main default <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> %{{ render.renderHTMLHeader(); }}% <script> function onClientSideRendering(a_event){ a_event.preventDefault(); fos.application.render({ template: "templates/window.tmpl", owner: document.body, args: { title: "Client side rendering", context: "Simple example of client side rendering" }, onResult: function(a_error, a_template){ } }); } function onServerSideRendering(a_event){ a_event.preventDefault(); fos.application.render({ template: "templates/window.tmpl", owner: document.body, renderMode: "server", args: { title: "Server side rendering", context: "Simple example of server side rendering" }, onResult: function(a_error, a_template){ } }); } </script> </head> <body> <div class="mainwrapper"> <div class="header markup"> Client Side Rendering </div> <div class="body-wrapper markup"> <div class="body markup"> <p class="example-link--container"><a onclick="onClientSideRendering(event);">Client side rendering</a></p> <p class="example-link--container"><a onclick="onServerSideRendering(event);">Server side rendering</a></p> </div> <div class="clear-body"></div> </div> </div> </body> </html>
页面模板具有两个链接,“客户端渲染”和“服务器端渲染”。 单击哪个将显示尚不可用的窗口。 但是有一个代码可以调用它们。 因此,让我们处理模板代码。
当我们单击“客户端渲染”链接时,我们调用onClientSideRendering()函数,该函数将渲染“ templates / window.tmpl”模板。 完全在客户端, 在应用程序设置中,clientRenderingMode参数设置为“ client”。 尽管这是默认值:-)。
function onClientSideRendering(a_event){ a_event.preventDefault(); fos.application.render({ template: "templates/window.tmpl", owner: document.body, args: { title: "Client side rendering", context: "Simple example of client side rendering" }, onResult: function(a_error, a_template){ } }); }
render方法实际上会渲染我们的窗口并将其放置在页面的主体中,如owner参数的属性所指定。 我们将2个参数传递给窗口模板:标题和上下文,实际上是将在显示的窗口中显示的内容。 有关该方法的更多信息,请参见
fos :: NClient :: Application :: render第二个链接调用onServerSideRendering()函数,该函数类似地呈现相同的模板,但在服务器端,并且客户端接收现成的HTML。 该模式在render方法的renderMode参数的属性中设置为值“ server”。
function onServerSideRendering(a_event){ a_event.preventDefault(); fos.application.render({ template: "templates/window.tmpl", owner: document.body, renderMode: "server", args: { title: "Server side rendering", context: "Simple example of server side rendering" }, onResult: function(a_error, a_template){ } }); }
创建一个弹出模板并编写包装模板
弹出窗口模板本身非常简单。 创建模板/ window.tmpl文件。 以下是其内容。
//~OPTIONS { args:{ fosWrapper: true, fosClass: "window", fosInclude: ["css/window.css"], title: "", context: "", } } //~BLOCK main default <div class="window-container"> <div class="window-close" name="close">x</div> <div class="window-title">${{args.title}}$</div> <div class="window-context">${{args.context}}$</div> </div>
在这里,您有两个新参数fosWrapper和fosClass。
让我们从fosWrapper开始。 如果将此标志设置为true,则将HTML模板放置在span容器中,并为其创建包装对象fos :: NRender :: Wrapper。
启动应用程序,转到
localhost :3001,然后单击链接“客户端渲染”。 弹出窗口是我们的模板。 窗口弹出窗口完全由CSS(css / window.css文件)实现-我刚刚提到您不会在寻找隐藏的JS :-)。
打开DevTools浏览器(Ctrl + Alt + i),转到“元素”选项卡并查看我们的窗口结构。

图中的蓝线标记了我们的跨接包装容器,该容器与fos :: NRender :: Wrapper对象连接。
模板的下一个系统参数是fosClass。 它只是将CSS类添加到包装器span容器中。
因此,一切都做得很好,但是如果我们尝试关闭弹出窗口,将一事无成。 是的,我们还没有写完结帐操作!
如前所述,如果系统参数fosWrapper为true,则将为模板创建包装对象fos :: NRender :: Wrapper。 它提供了用于与客户端上的模板进行交互的标准接口。 要重新定义模板的标准包装器,只需创建一个名称与以下格式对应的模块即可[PATTERN NAME] .wrapper.js,并且该模块应继承自fos :: NRender :: Wrapper类。
现在为模板/ window.tmpl模板创建一个包装文件。 当您单击符号“ x”时,新类将不得不关闭我们的弹出窗口。
文件模板/ window.wrapper.js:
fos.module({ name: "templates/window.wrapper.js", dependencies: ["fos:NRender/Wrapper.js"], module: function(Wrapper){ return function(a_initializeOptions) { var self = this; Wrapper.call(this, a_initializeOptions); var parentAttach = this._attach; this._attach = function(a_cb) { parentAttach.call(this, function(){ fos.addDomListener(fos.select(self.getDomElement(), "[name=close]")[0], "click", function(){ self.getDomElement().classList.add("window-hide"); setTimeout(function() { self.destroy(); }, 2000); }); a_cb(); }); } } } });
让我们分析模块的内容。 首先,我们连接基类fos :: NRender :: Wrapper并通过call方法从其继承。
fos.module({ name: "templates/window.wrapper.js", dependencies: ["fos:NRender/Wrapper.js"], module: function(Wrapper){ return function(a_initializeOptions) { var self = this; Wrapper.call(this, a_initializeOptions); ...
重新定义fos :: NRender :: Wrapper :: _ attach方法后,当模板与对象关联时将调用该方法。 在这种方法中,我们将连接单击链接以关闭窗口的事件。 只需通过声明方法即可完成覆盖,但是在开始时,我们必须保留对父实现的引用。 该方法具有“异步性质”,因此我们将操作的实现放入父实现的回调函数中。
... var parentAttach = this._attach; this._attach = function(a_cb) { parentAttach.call(this, function(){ fos.addDomListener(fos.select(self.getDomElement(), "[name=close]")[0], "click", function(){ self.getDomElement().classList.add("window-hide"); setTimeout(function() { self.destroy(); }, 2000); }); a_cb(); }); } ...
连接到单击符号“ x”的事件,我们通过调用fos :: addDomListener来执行,该事件在更改DOM元素的父代时不会重置连接的事件。
在事件处理程序中,我们关闭窗口。 首先,我们通过添加CSS类“ window-hide”将窗口从屏幕上移除。 动画完成后,我们调用fos :: NRender :: Wrapper :: destroy方法,该方法将删除模板和包装对象。
编写,发布和重新加入的所有应用程序!!!
node application.js
官方开发网站链接到示例