Angular开发实践之服务端渲染
这篇文章主要介绍了Angular开发实践之服务端渲染,现在分享给大家,也给大家做个参考。
Angular Universal
Angular在服务端渲染方面提供一套前后端同构解决方案,它就是Angular Universal(统一平台),一项在服务端运行 Angular 应用的技术。
标准的 Angular 应用会执行在浏览器中,它会在 DOM 中渲染页面,以响应用户的操作。
而 Angular Universal 会在服务端通过一个被称为服务端渲染(server-side rendering - SSR)的过程生成静态的应用页面。
它可以生成这些页面,并在浏览器请求时直接用它们给出响应。 它也可以把页面预先生成为 HTML 文件,然后把它们作为静态文件供服务器使用。
工作原理
要制作一个 Universal 应用,就要安装 platform-server
包。 platform-server 包提供了服务端的 DOM 实现、XMLHttpRequest 和其它底层特性,但不再依赖浏览器。
你要使用 platform-server
模块而不是 platform-browser
模块来编译这个客户端应用,并且在一个 Web 服务器上运行这个 Universal 应用。
服务器(下面的示例中使用的是 Node Express 服务器)会把客户端对应用页面的请求传给 renderModuleFactory
函数。
renderModuleFactory 函数接受一个模板 HTML 页面(通常是 index.html)、一个包含组件的 Angular 模块和一个用于决定该显示哪些组件的路由作为输入。
该路由从客户端的请求中传给服务器。 每次请求都会给出所请求路由的一个适当的视图。
renderModuleFactory 在模板中的 <app>
标记中渲染出哪个视图,并为客户端创建一个完成的 HTML 页面。
最后,服务器就会把渲染好的页面返回给客户端。
为什么要服务端渲染
三个主要原因:
帮助网络爬虫(SEO)
提升在手机和低功耗设备上的性能
迅速显示出第一个页面
帮助网络爬虫(SEO)
Google、Bing、百度、Facebook、Twitter 和其它搜索引擎或社交媒体网站都依赖网络爬虫去索引你的应用内容,并且让它的内容可以通过网络搜索到。
这些网络爬虫可能不会像人类那样导航到你的具有高度交互性的 Angular 应用,并为其建立索引。
Angular Universal 可以为你生成应用的静态版本,它易搜索、可链接,浏览时也不必借助 JavaScript。它也让站点可以被预览,因为每个 URL 返回的都是一个完全渲染好的页面。
启用网络爬虫通常被称为搜索引擎优化 (SEO)。
提升手机和低功耗设备上的性能
有些设备不支持 JavaScript 或 JavaScript 执行得很差,导致用户体验不可接受。 对于这些情况,你可能会需要该应用的服务端渲染、无 JavaScript 的版本。 虽然有一些限制,不过这个版本可能是那些完全没办法使用该应用的人的唯一选择。
快速显示首页
快速显示首页对于吸引用户是至关重要的。
如果页面加载超过了三秒中,那么 53% 的移动网站会被放弃。 你的应用需要启动的更快一点,以便在用户决定做别的事情之前吸引他们的注意力。
使用 Angular Universal,你可以为应用生成“着陆页”,它们看起来就和完整的应用一样。 这些着陆页是纯 HTML,并且即使 JavaScript 被禁用了也能显示。 这些页面不会处理浏览器事件,不过它们可以用 routerLink 在这个网站中导航。
在实践中,你可能要使用一个着陆页的静态版本来保持用户的注意力。 同时,你也会在幕后加载完整的 Angular 应用。 用户会认为着陆页几乎是立即出现的,而当完整的应用加载完之后,又可以获得完全的交互体验。
示例解析
下面将基于我在GitHub上的示例项目 angular-universal-starter 来进行讲解。
这个项目与第一篇的示例项目一样,都是基于 Angular CLI进行开发构建的,因此它们的区别只在于服务端渲染所需的那些配置上。
安装工具
在开始之前,下列包是必须安装的(示例项目均已配置好,只需 npm install
即可):
@angular/platform-server
- Universal 的服务端元件。@nguniversal/module-map-ngfactory-loader
- 用于处理服务端渲染环境下的惰性加载。@nguniversal/express-engine
- Universal 应用的 Express 引擎。ts-loader
- 用于对服务端应用进行转译。express
- Node Express 服务器
使用下列命令安装它们:
npm install --save @angular/platform-server @nguniversal/module-map-ngfactory-loader ts-loader @nguniversal/express-engine express
项目配置
配置工作有:
创建服务端应用模块:src/app/app.server.module.ts
修改客户端应用模块:src/app/app.module.ts
创建服务端应用的引导程序文件:src/main.server.ts
修改客户端应用的引导程序文件:src/main.ts
创建 TypeScript 的服务端配置:src/tsconfig.server.json
修改 @angular/cli 的配置文件:.angular-cli.json
创建 Node Express 的服务程序:server.ts
创建服务端预渲染的程序:prerender.ts
创建 Webpack 的服务端配置:webpack.server.config.js
1、创建服务端应用模块:src/app/app.server.module.ts
import { NgModule } from '@angular/core'; import { ServerModule, ServerTransferStateModule } from '@angular/platform-server'; import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader'; import { AppBrowserModule } from './app.module'; import { AppComponent } from './app.component'; // 可以注册那些在 Universal 环境下运行应用时特有的服务提供商 @NgModule({ imports: [ AppBrowserModule, // 客户端应用的 AppModule ServerModule, // 服务端的 Angular 模块 ModuleMapLoaderModule, // 用于实现服务端的路由的惰性加载 ServerTransferStateModule, // 在服务端导入,用于实现将状态从服务器传输到客户端 ], bootstrap: [AppComponent], }) export class AppServerModule { }
服务端应用模块(习惯上叫作 AppServerModule)是一个 Angular 模块,它包装了应用的根模块 AppModule,以便 Universal 可以在你的应用和服务器之间进行协调。 AppServerModule 还会告诉 Angular 再把你的应用以 Universal 方式运行时,该如何引导它。
2、修改客户端应用模块:src/app/app.module.ts
@NgModule({ imports: [ AppRoutingModule, BrowserModule.withServerTransition({appId: 'my-app'}), TransferHttpCacheModule, // 用于实现服务器到客户端的请求传输缓存,防止客户端重复请求服务端已完成的请求 BrowserTransferStateModule, // 在客户端导入,用于实现将状态从服务器传输到客户端 HttpClientModule ], declarations: [ AppComponent, HomeComponent ], providers: [], bootstrap: [AppComponent] }) export class AppBrowserModule { constructor(@Inject(PLATFORM_ID) private platformId: Object, @Inject(APP_ID) private appId: string) { // 判断运行环境为客户端还是服务端 const platform = isPlatformBrowser(platformId) ? 'in the browser' : 'on the server'; console.log(`Running ${platform} with appId=${appId}`); } }
将 NgModule
的元数据中 BrowserModule 的导入改成 BrowserModule.withServerTransition({appId: 'my-app'}),Angular 会把 appId 值(它可以是任何字符串)添加到服务端渲染页面的样式名中,以便它们在客户端应用启动时可以被找到并移除。
此时,我们可以通过依赖注入(@Inject(PLATFORM_ID)
及 @Inject(APP_ID)
)取得关于当前平台和 appId 的运行时信息:
constructor(@Inject(PLATFORM_ID) private platformId: Object, @Inject(APP_ID) private appId: string) { // 判断运行环境为客户端还是服务端 const platform = isPlatformBrowser(platformId) ? 'in the browser' : 'on the server'; console.log(`Running ${platform} with appId=${appId}`); }
3、创建服务端应用的引导程序文件:src/main.server.ts
该文件导出服务端模块:
export { AppServerModule } from './app/app.server.module';
4、修改客户端应用的引导程序文件:src/main.ts
监听 DOMContentLoaded 事件,在发生 DOMContentLoaded 事件时运行我们的代码,以使 TransferState 正常工作
import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppBrowserModule } from './app/app.module'; import { environment } from './environments/environment'; if (environment.production) { enableProdMode(); } // 在 DOMContentLoaded 时运行我们的代码,以使 TransferState 正常工作 document.addEventListener('DOMContentLoaded', () => { platformBrowserDynamic().bootstrapModule(AppBrowserModule); });
5、创建 TypeScript 的服务端配置:src/tsconfig.server.json
{ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "../out-tsc/app", "baseUrl": "./", "module": "commonjs", "types": [ "node" ] }, "exclude": [ "test.ts", "**/*.spec.ts" ], "angularCompilerOptions": { "entryModule": "app/app.server.module#AppServerModule" } }
与 tsconfig.app.json
的差异在于:
module 属性必须是 commonjs,这样它才能被 require() 方法导入你的服务端应用。
angularCompilerOptions 部分有一些面向 AOT 编译器的选项:
entryModule - 服务端应用的根模块,其格式为 path/to/file#ClassName。
6、修改 @angular/cli 的配置文件:.angular-cli.json
在 apps
下添加:
{ "platform": "server", "root": "src", "outDir": "dist/server", "assets": [ "assets", "favicon.ico" ], "index": "index.html", "main": "main.server.ts", "test": "test.ts", "tsconfig": "tsconfig.server.json", "testTsconfig": "tsconfig.spec.json", "prefix": "", "styles": [ "styles.scss" ], "scripts": [], "environmentSource": "environments/environment.ts", "environments": { "dev": "environments/environment.ts", "prod": "environments/environment.prod.ts" } }
7、创建 Node Express 的服务程序:server.ts
import 'zone.js/dist/zone-node'; import 'reflect-metadata'; import { enableProdMode } from '@angular/core'; import * as express from 'express'; import { join } from 'path'; import { readFileSync } from 'fs'; // Faster server renders w/ Prod mode (dev mode never needed) enableProdMode(); // Express server const app = express(); const PORT = process.env.PORT || 4000; const DIST_FOLDER = join(process.cwd(), 'dist'); // Our index.html we'll use as our template const template = readFileSync(join(DIST_FOLDER, 'browser', 'index.html')).toString(); // * NOTE :: leave this as require() since this file is built Dynamically from webpack const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main.bundle'); // Express Engine import { ngExpressEngine } from '@nguniversal/express-engine'; // Import module map for lazy loading import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader'; // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine) app.engine('html', ngExpressEngine({ bootstrap: AppServerModuleNgFactory, providers: [ provideModuleMap(LAZY_MODULE_MAP) ] })); app.set('view engine', 'html'); app.set('views', join(DIST_FOLDER, 'browser')); /* - Example Express Rest API endpoints - app.get('/api/**', (req, res) => { }); */ // Server static files from /browser app.get('*.*', express.static(join(DIST_FOLDER, 'browser'), { maxAge: '1y' })); // ALl regular routes use the Universal engine app.get('*', (req, res) => { res.render('index', {req}); }); // Start up the Node server app.listen(PORT, () => { console.log(`Node Express server listening on http://localhost:${PORT}`); });
8、创建服务端预渲染的程序:prerender.ts
// Load zone.js for the server. import 'zone.js/dist/zone-node'; import 'reflect-metadata'; import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs'; import { join } from 'path'; import { enableProdMode } from '@angular/core'; // Faster server renders w/ Prod mode (dev mode never needed) enableProdMode(); // Import module map for lazy loading import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader'; import { renderModuleFactory } from '@angular/platform-server'; import { ROUTES } from './static.paths'; // * NOTE :: leave this as require() since this file is built Dynamically from webpack const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main.bundle'); const BROWSER_FOLDER = join(process.cwd(), 'browser'); // Load the index.html file containing referances to your application bundle. const index = readFileSync(join('browser', 'index.html'), 'utf8'); let previousRender = Promise.resolve(); // Iterate each route path ROUTES.forEach(route => { const fullPath = join(BROWSER_FOLDER, route); // Make sure the directory structure is there if (!existsSync(fullPath)) { mkdirSync(fullPath); } // Writes rendered HTML to index.html, replacing the file if it already exists. previousRender = previousRender.then(_ => renderModuleFactory(AppServerModuleNgFactory, { document: index, url: route, extraProviders: [ provideModuleMap(LAZY_MODULE_MAP) ] })).then(html => writeFileSync(join(fullPath, 'index.html'), html)); });
9、创建 Webpack 的服务端配置:webpack.server.config.js
Universal 应用不需要任何额外的 Webpack 配置,Angular CLI 会帮我们处理它们。但是由于本例子的 Node Express 的服务程序是 TypeScript 应用(server.ts及prerender.ts),所以要使用 Webpack 来转译它。这里不讨论 Webpack 的配置,需要了解的移步 Webpack官网
// Work around for https://github.com/angular/angular-cli/issues/7200 const path = require('path'); const webpack = require('webpack'); module.exports = { entry: { server: './server.ts', // This is our Express server for Dynamic universal prerender: './prerender.ts' // This is an example of Static prerendering (generative) }, target: 'node', resolve: {extensions: ['.ts', '.js']}, externals: [/(node_modules|main\..*\.js)/,], // Make sure we include all node_modules etc output: { path: path.join(__dirname, 'dist'), // Puts the output at the root of the dist folder filename: '[name].js' }, module: { rules: [ {test: /\.ts$/, loader: 'ts-loader'} ] }, plugins: [ new webpack.ContextReplacementPlugin( /(.+)?angular(\\|\/)core(.+)?/, // fixes WARNING Critical dependency: the request of a dependency is an expression path.join(__dirname, 'src'), // location of your src {} // a map of your routes ), new webpack.ContextReplacementPlugin( /(.+)?express(\\|\/)(.+)?/, // fixes WARNING Critical dependency: the request of a dependency is an expression path.join(__dirname, 'src'), {} ) ] };
测试配置
通过上面的配置,我们就制作完成一个可在服务端渲染的 Angular Universal 应用。
在 package.json 的 scripts 区配置 build 和 serve 有关的命令:
{ "scripts": { "ng": "ng", "start": "ng serve -o", "ssr": "npm run build:ssr && npm run serve:ssr", "prerender": "npm run build:prerender && npm run serve:prerender", "build": "ng build", "build:client-and-server-bundles": "ng build --prod && ng build --prod --app 1 --output-hashing=false", "build:prerender": "npm run build:client-and-server-bundles && npm run webpack:server && npm run generate:prerender", "build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server", "generate:prerender": "cd dist && node prerender", "webpack:server": "webpack --config webpack.server.config.js --progress --colors", "serve:prerender": "cd dist/browser && http-server", "serve:ssr": "node dist/server" } }
开发只需运行 npm run start
执行 npm run ssr
编译应用程序,并启动一个Node Express来为应用程序提供服务 http://localhost:4000
dist目录:
执行npm run prerender - 编译应用程序并预渲染应用程序文件,启动一个演示http服务器,以便您可以查看它 http://localhost:8080
注意: 要将静态网站部署到静态托管平台,您必须部署dist/browser文件夹, 而不是dist文件夹
dist目录:
根据项目实际的路由信息并在根目录的 static.paths.ts
中配置,提供给 prerender.ts 解析使用。
export const ROUTES = [ '/', '/lazy' ];
因此,从dist目录可以看到,服务端预渲染会根据配置好的路由在 browser 生成对应的静态index.html。如 /
对应 /index.html
,/lazy
对应 /lazy/index.html
。
服务器到客户端的状态传输
在前面的介绍中,我们在 app.server.module.ts
中导入了 ServerTransferStateModule
,在 app.module.ts
中导入了 BrowserTransferStateModule
和 TransferHttpCacheModule
。
这三个模块都与服务器到客户端的状态传输有关:
ServerTransferStateModule
:在服务端导入,用于实现将状态从服务器传输到客户端BrowserTransferStateModule
:在客户端导入,用于实现将状态从服务器传输到客户端TransferHttpCacheModule
:用于实现服务器到客户端的请求传输缓存,防止客户端重复请求服务端已完成的请求
使用这几个模块,可以解决 http请求在服务端和客户端分别请求一次 的问题。
比如在 home.component.ts
中有如下代码:
import { Component, OnDestroy, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.scss'] }) export class HomeComponent implements OnInit, OnDestroy { constructor(public http: HttpClient) { } ngOnInit() { this.poiSearch(this.keyword, '北京市').subscribe((data: any) => { console.log(data); }); } ngOnDestroy() { } poiSearch(text: string, city?: string): Observable<any> { return this.http.get(encodeURI(`http://restapi.amap.com/v3/place/text?keywords=${text}&city=${city}&offset=20&key=55f909211b9950837fba2c71d0488db9&extensions=all`)); } }
代码运行之后,
服务端请求并打印:
客户端再一次请求并打印:
方法1:使用 TransferHttpCacheModule
使用 TransferHttpCacheModule
很简单,代码不需要改动。在 app.module.ts
中导入之后,Angular自动会将服务端请求缓存到客户端,换句话说就是服务端请求到数据会自动传输到客户端,客户端接收到数据之后就不会再发送请求了。
方法2:使用 BrowserTransferStateModule
该方法稍微复杂一些,需要改动一些代码。
调整 home.component.ts
代码如下:
import { Component, OnDestroy, OnInit } from '@angular/core'; import { makeStateKey, TransferState } from '@angular/platform-browser'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; const KFCLIST_KEY = makeStateKey('kfcList'); @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.scss'] }) export class HomeComponent implements OnInit, OnDestroy { constructor(public http: HttpClient, private state: TransferState) { } ngOnInit() { // 采用一个标记来区分服务端是否已经拿到了数据,如果没拿到数据就在客户端请求,如果已经拿到数据就不发请求 const kfcList:any[] = this.state.get(KFCLIST_KEY, null as any); if (!this.kfcList) { this.poiSearch(this.keyword, '北京市').subscribe((data: any) => { console.log(data); this.state.set(KFCLIST_KEY, data as any); // 存储数据 }); } } ngOnDestroy() { if (typeof window === 'object') { this.state.set(KFCLIST_KEY, null as any); // 删除数据 } } poiSearch(text: string, city?: string): Observable<any> { return this.http.get(encodeURI(`http://restapi.amap.com/v3/place/text?keywords=${text}&city=${city}&offset=20&key=55f909211b9950837fba2c71d0488db9&extensions=all`)); } }
使用
const KFCLIST_KEY = makeStateKey('kfcList')
创建储存传输数据的 StateKey在
HomeComponent
的构造函数中注入TransferState
在
ngOnInit
中根据this.state.get(KFCLIST_KEY, null as any)
判断数据是否存在(不管是服务端还是客户端),存在就不再请求,不存在则请求数据并通过this.state.set(KFCLIST_KEY, data as any)
存储传输数据在
ngOnDestroy
中根据当前是否客户端来决定是否将存储的数据进行删除
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
Atas ialah kandungan terperinci Angular开发实践之服务端渲染. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Arahan NETSTART ialah arahan terbina dalam Windows yang boleh digunakan untuk memulakan dan menghentikan perkhidmatan dan program lain. Kadangkala, anda mungkin menghadapi ralat NetHelpmsg2186 semasa menjalankan arahan ini. Kebanyakan pengguna yang menghadapi ralat ini cuba memulakan semula perkhidmatan Kemas Kini Windows dengan menjalankan arahan NETSTARTWUAUSERV. Jika perkhidmatan Kemas Kini Windows dilumpuhkan atau tidak berjalan, sistem anda mungkin berisiko kerana anda tidak akan dapat mendapatkan kemas kini terkini. Mari kita terokai secara terperinci mengapa ralat ini berlaku dan cara memintasnya. OK? Apakah ralat 2186? Perkhidmatan Windows Update memasang kemas kini kritikal dan ciri keselamatan terkini

Perkhidmatan Pusat Keselamatan ialah fungsi perlindungan komputer terbina dalam sistem win10, yang boleh melindungi keselamatan komputer dalam masa nyata Walau bagaimanapun, sesetengah pengguna menghadapi situasi di mana perkhidmatan Pusat Keselamatan dinyahdayakan semasa but komputer. Ia sangat mudah. Anda boleh membuka panel perkhidmatan, cari item SecurityCenter, kemudian klik kanan untuk membuka tetingkap sifatnya, tetapkan jenis permulaan kepada automatik, dan kemudian klik Mula untuk memulakan perkhidmatan semula. Perkara yang perlu dilakukan jika perkhidmatan Pusat Keselamatan Win10 dilumpuhkan: 1. Tekan "Win+R" untuk membuka tetingkap "Operasi". 2. Kemudian masukkan arahan "services.msc" dan tekan Enter 3. Kemudian cari item "SecurityCenter" dalam tetingkap kanan dan klik dua kali untuk membuka tetingkap sifatnya.

Angular.js ialah platform JavaScript yang boleh diakses secara bebas untuk mencipta aplikasi dinamik. Ia membolehkan anda menyatakan pelbagai aspek aplikasi anda dengan cepat dan jelas dengan memanjangkan sintaks HTML sebagai bahasa templat. Angular.js menyediakan pelbagai alatan untuk membantu anda menulis, mengemas kini dan menguji kod anda. Selain itu, ia menyediakan banyak ciri seperti penghalaan dan pengurusan borang. Panduan ini akan membincangkan cara memasang Angular pada Ubuntu24. Mula-mula, anda perlu memasang Node.js. Node.js ialah persekitaran berjalan JavaScript berdasarkan enjin ChromeV8 yang membolehkan anda menjalankan kod JavaScript pada bahagian pelayan. Untuk berada di Ub

Sambungan desktop jauh telah membawa kemudahan kepada kehidupan harian ramai pengguna Sesetengah orang ingin menggunakan arahan untuk menyambung dari jauh, yang mana lebih mudah untuk dikendalikan. Perkhidmatan Sambungan Desktop Jauh boleh membantu anda menyelesaikan masalah ini dengan menggunakan arahan untuk membukanya. Cara menyediakan arahan sambungan desktop jauh: Kaedah 1. Sambung dari jauh dengan menjalankan arahan 1. Tekan "Win+R" untuk membuka "Run" dan masukkan mstsc2, kemudian klik "Show Options" 3. Masukkan alamat IP dan klik "Sambung". 4. Ia akan menunjukkan bahawa ia bersambung. Kaedah 2: Sambung dari jauh melalui command prompt 1. Tekan "Win+R" untuk membuka "Run" dan masukkan cmd2 Dalam "Command Prompt" masukkan mstsc/v:192.168.1.250/console.

Komputer mempunyai banyak perkhidmatan sistem untuk menyokong aplikasi pelbagai program. Jika komputer tidak mempunyai bunyi dan kebanyakan perkhidmatan audio tidak dihidupkan selepas menyelesaikan masalah perkakasan, bagaimana anda mendayakan perkhidmatan audio dalam win7? Ramai rakan keliru, jadi untuk persoalan bagaimana untuk membolehkan perkhidmatan audio dalam win7, editor di bawah akan memperkenalkan cara untuk membolehkan perkhidmatan audio dalam win7. Bagaimana untuk mendayakan perkhidmatan audio dalam win7. 1. Cari komputer pada desktop komputer di bawah sistem Windows 7, klik kanan dan pilih pilihan pengurusan. 2. Cari dan buka item perkhidmatan di bawah Perkhidmatan dan Aplikasi dalam antara muka pengurusan komputer yang terbuka. Cari WindowsAudio pada antara muka perkhidmatan di sebelah kanan dan klik dua kali untuk membuka pengubahsuaian. 4. Tukar kepada projek biasa dan klik Mula untuk mendayakan fungsi.

1. Mula-mula buka pelan reka bentuk yang akan diberikan dalam Kujiale. 2. Kemudian buka pemaparan paparan atas di bawah menu pemaparan. 3. Kemudian klik Ortogonal dalam tetapan parameter dalam antara muka paparan paparan atas. 4. Akhir sekali, selepas melaraskan sudut model, klik Render Now untuk memaparkan paparan atas ortogon.

Apakah cara yang betul untuk memulakan semula perkhidmatan dalam Linux? Apabila menggunakan sistem Linux, kami sering menghadapi situasi di mana kami perlu memulakan semula perkhidmatan tertentu, tetapi kadangkala kami mungkin menghadapi beberapa masalah semasa memulakan semula perkhidmatan, seperti perkhidmatan tidak benar-benar berhenti atau bermula. Oleh itu, adalah sangat penting untuk menguasai cara yang betul untuk memulakan semula perkhidmatan. Di Linux, anda biasanya boleh menggunakan perintah systemctl untuk mengurus perkhidmatan sistem. Perintah systemctl adalah sebahagian daripada pengurus sistem systemd

Dengan perkembangan pesat Internet, teknologi pembangunan bahagian hadapan juga sentiasa bertambah baik dan berulang. PHP dan Angular ialah dua teknologi yang digunakan secara meluas dalam pembangunan bahagian hadapan. PHP ialah bahasa skrip sebelah pelayan yang boleh mengendalikan tugas seperti memproses borang, menjana halaman dinamik dan mengurus kebenaran akses. Angular ialah rangka kerja JavaScript yang boleh digunakan untuk membangunkan aplikasi satu halaman dan membina aplikasi web berkomponen. Artikel ini akan memperkenalkan cara menggunakan PHP dan Angular untuk pembangunan bahagian hadapan, dan cara menggabungkannya
